// Path: src/main/java/nl/tudelft/ewi/gitolite/objects/Identifiable.java
// public interface Identifiable extends Comparable<Identifiable>, Serializable {
// 
// 	String getPattern();
// 
// 	@Override
// 	default int compareTo(Identifiable o) {
// 		return getPattern().compareTo(o.getPattern());
// 	}
// 
// }
// 
// Path: src/main/java/nl/tudelft/ewi/gitolite/objects/Identifier.java
// @Value
// public class Identifier implements Identifiable {
// 
// 	/**
// 	 * The name for the identifier
// 	 */
// 	private final String pattern;
// 
// 	private final static WeakHashMap<String, WeakReference<Identifier>> identifiableMap = new WeakHashMap<>();
// 
// 	/**
// 	 * Get an identifier. As {@code Identifiers} should be immutable, they are stored in a
// 	 * {@code WeakHashMap} for caching purposes. This method tries to find {@code Identifiers}
// 	 * in the cache first, and only creates a new instance if not. Therefore, this method is
// 	 * preferred over using a constructor.
// 	 *
// 	 * @param name Name for the identifier.
// 	 * @return Identifier
// 	 */
// 	public static Identifier valueOf(String name) {
// 		WeakReference<Identifier> ref = identifiableMap.get(name);
// 		Identifier identifiable;
// 		if(ref == null || (identifiable = ref.get()) == null) {
// 			identifiable = new Identifier(name);
// 			identifiableMap.put(name, new WeakReference<>(identifiable));
// 		}
// 		return identifiable;
// 	}
// 
// }
// 
// Path: src/main/java/nl/tudelft/ewi/gitolite/util/RecursiveStreamingGroup.java
// public interface RecursiveStreamingGroup<R extends RecursiveStreamingGroup<? extends StreamingGroup, ? extends T>, T> extends StreamingGroup<T> {
// 
// 	/**
// 	 * @return the own members for this group, excluding the recursive members inherited from the groups.
// 	 */
// 	Stream<T> getOwnMembersStream();
// 
// 	/**
// 	 * @return the groups in this group.
// 	 */
// 	Stream<R> getOwnGroupsStream();
// 
// 	/**
// 	 * Add a group to this group.
// 	 * @param group Group to add
// 	 */
// 	void add(R group);
// 
// 	/**
// 	 * @return the members inherited from the groups.
// 	 */
// 	default Stream<T> getRecursiveInheritedStream() {
// 		return getOwnGroupsStream().flatMap(StreamingGroup::getMembersStream);
// 	}
// 
// 	@Override
// 	default Stream<T> getMembersStream() {
// 		return Stream.concat(getRecursiveInheritedStream(), getOwnMembersStream());
// 	}
// 
// }


import com.google.common.collect.Lists;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import com.google.common.base.Joiner;
import lombok.Singular;
import nl.tudelft.ewi.gitolite.objects.Identifiable;
import nl.tudelft.ewi.gitolite.objects.Identifier;
import nl.tudelft.ewi.gitolite.util.RecursiveStreamingGroup;
import java.io.IOException;
import java.io.Writer;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Stream;
package nl.tudelft.ewi.gitolite.parser.rules;





/**
 * @author Jan-Willem Gmelig Meyling
 */
@Builder
@EqualsAndHashCode(doNotUseGetters = true)
public class InlineUserGroup implements RecursiveStreamingGroup<GroupRule, Identifier>, Writable {

	@Singular
	private final List<GroupRule> groups;

	@Singular
	private final List<Identifier> members;

	public InlineUserGroup(GroupRule... groups) {
		this(Arrays.asList(groups), Collections.emptyList());
	}

	public InlineUserGroup(Identifier... identifiable) {
		this(Collections.emptyList(), Arrays.asList(identifiable));
	}

// Path: src/main/java/nl/tudelft/ewi/gitolite/objects/Identifiable.java
// public interface Identifiable extends Comparable<Identifiable>, Serializable {
// 
// 	String getPattern();
// 
// 	@Override
// 	default int compareTo(Identifiable o) {
// 		return getPattern().compareTo(o.getPattern());
// 	}
// 
// }
// 
// Path: src/main/java/nl/tudelft/ewi/gitolite/objects/Identifier.java
// @Value
// public class Identifier implements Identifiable {
// 
// 	/**
// 	 * The name for the identifier
// 	 */
// 	private final String pattern;
// 
// 	private final static WeakHashMap<String, WeakReference<Identifier>> identifiableMap = new WeakHashMap<>();
// 
// 	/**
// 	 * Get an identifier. As {@code Identifiers} should be immutable, they are stored in a
// 	 * {@code WeakHashMap} for caching purposes. This method tries to find {@code Identifiers}
// 	 * in the cache first, and only creates a new instance if not. Therefore, this method is
// 	 * preferred over using a constructor.
// 	 *
// 	 * @param name Name for the identifier.
// 	 * @return Identifier
// 	 */
// 	public static Identifier valueOf(String name) {
// 		WeakReference<Identifier> ref = identifiableMap.get(name);
// 		Identifier identifiable;
// 		if(ref == null || (identifiable = ref.get()) == null) {
// 			identifiable = new Identifier(name);
// 			identifiableMap.put(name, new WeakReference<>(identifiable));
// 		}
// 		return identifiable;
// 	}
// 
// }
// 
// Path: src/main/java/nl/tudelft/ewi/gitolite/util/RecursiveStreamingGroup.java
// public interface RecursiveStreamingGroup<R extends RecursiveStreamingGroup<? extends StreamingGroup, ? extends T>, T> extends StreamingGroup<T> {
// 
// 	/**
// 	 * @return the own members for this group, excluding the recursive members inherited from the groups.
// 	 */
// 	Stream<T> getOwnMembersStream();
// 
// 	/**
// 	 * @return the groups in this group.
// 	 */
// 	Stream<R> getOwnGroupsStream();
// 
// 	/**
// 	 * Add a group to this group.
// 	 * @param group Group to add
// 	 */
// 	void add(R group);
// 
// 	/**
// 	 * @return the members inherited from the groups.
// 	 */
// 	default Stream<T> getRecursiveInheritedStream() {
// 		return getOwnGroupsStream().flatMap(StreamingGroup::getMembersStream);
// 	}
// 
// 	@Override
// 	default Stream<T> getMembersStream() {
// 		return Stream.concat(getRecursiveInheritedStream(), getOwnMembersStream());
// 	}
// 
// }


// Path: src/main/java/nl/tudelft/ewi/gitolite/parser/rules/InlineUserGroup.java
import com.google.common.collect.Lists;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import com.google.common.base.Joiner;
import lombok.Singular;
import nl.tudelft.ewi.gitolite.objects.Identifiable;
import nl.tudelft.ewi.gitolite.objects.Identifier;
import nl.tudelft.ewi.gitolite.util.RecursiveStreamingGroup;
import java.io.IOException;
import java.io.Writer;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Stream;

package nl.tudelft.ewi.gitolite.parser.rules;





/**
 * @author Jan-Willem Gmelig Meyling
 */
@Builder
@EqualsAndHashCode(doNotUseGetters = true)
public class InlineUserGroup implements RecursiveStreamingGroup<GroupRule, Identifier>, Writable {

	@Singular
	private final List<GroupRule> groups;

	@Singular
	private final List<Identifier> members;

	public InlineUserGroup(GroupRule... groups) {
		this(Arrays.asList(groups), Collections.emptyList());
	}

	public InlineUserGroup(Identifier... identifiable) {
		this(Collections.emptyList(), Arrays.asList(identifiable));
	}

	public InlineUserGroup(Collection<? extends GroupRule> groups, Collection<? extends Identifier> members) {