package common;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Universe<E> {
	
	private final List<E> ie;
	private final Map<E,Integer> ei;
	
	public Universe(Collection<? extends E> c){
		this.ie = new ArrayList<E>(c);
		this.ei = new HashMap<>();
		for(int i=0; i<ie.size(); ++i){
			ei.put(ie.get(i), i);
		}
	}
	
	public Universe(Stream<? extends E> s){
		this.ie = s.collect(Collectors.toList());
		this.ei = new HashMap<>();
		for(int i=0; i<ie.size(); ++i){
			ei.put(ie.get(i), i);
		}
	}
	
	public boolean contains(Object o){
		return ei.containsKey(o);
	}
	
	public int size(){
		return ie.size();
	}
	
	/**
	 * <p>Returns the object having index {@code i} in this Universe.</p>
	 * @param i the index of the element of this Universe to be returned
	 * @return the object having index {@code i} in this Universe
	 * @throws IndexOutOfBoundsException if {@code i} is less than 0 or greater than or equal to the 
	 * size of the Universe
	 */
	public E get(int i){
		return ie.get(i);
	}
	
	public int index(E e){
		return ei.get(e);
	}
	
	public BackedSet<E> set(Collection<? extends E> c){
		return new BackedSet<E>(this,c);
	}
	
	@Override
	public int hashCode(){
		if(hash==null){
			hash = ie.hashCode();
		}
		return hash;
	}
	
	private Integer hash = null;
	
	@Override
	public boolean equals(Object o){
		if(o instanceof Universe<?>){
			Universe<?> u = (Universe<?>) o;
			return ie.equals(u.ie) && ei.equals(u.ei); 
		}
		return false;
	}
	
  /**
   * <p>A convenience method returning an empty BackedSet backed by this Universe.</p>
   * @return an empty BackedSet backed by this Universe
   */
	public BackedSet<E> back(){
		return new BackedSet<>(this);
	}
	
  /**
   * <p>A convenience method returning a BackedSet backed by this Universe and containing the 
   * contents of {@code c}.</p>
   * @return a BackedSet backed by this Universe and containing the contents of {@code c}
   * @throws OutOfUniverseException if any element of {@code c} is not in this Universe
   */
	public BackedSet<E> back(Collection<? extends E> c){
		return new BackedSet<>(this, c);
	}
}

@@ -211,99 +211,702 @@
 m;%0A%0A
-public class Universe%3CE%3E %7B%0A%09%0A%09private final List%3CE%3E ie;%0A%09private final Map%3CE,Integer%3E ei;%0A%09
+/**%0A * %3Cp%3EA special immutable collection where each element maps one-to-one with an integer. Used as a %0A * backing for BackedSets, which identify their elements as indices in a BigInteger; such an index %0A * is the integer corresponding to the element in that BackedSet's Universe.%3C/p%3E%0A * @author fiveham%0A * @param %3CE%3E the type of the elements of this universe and the parameter-type of BackedSets built %0A * on this Universe%0A * @see java.util.EnumSet%0A */%0Apublic class Universe%3CE%3E %7B%0A%09%0A%09private final List%3CE%3E ie;%0A%09private final Map%3CE,Integer%3E ei;%0A%09%0A%09/**%0A%09 * %3Cp%3EConstructs a Universe containing exactly the elements of %7B@code c%7D.%3C/p%3E%0A%09 * @param c a set whose elements will become this Universe%0A%09 */
 %0A%09pu
@@ -1069,32 +1069,191 @@
 ), i);%0A%09%09%7D%0A%09%7D%0A%09%0A
+%09/**%0A%09 * %3Cp%3EConstructs a Universe containing exactly the unique elements of %7B@code s%7D.%3C/p%3E%0A%09 * @param s a stream whose contents will become this Universe%0A%09 */%0A
 %09public Universe
@@ -1423,75 +1423,436 @@
 %0A%09%0A%09
-public boolean contains(Object o)%7B%0A%09%09return ei.containsKey(o);%0A%09%7D%0A%09
+/**%0A%09 * %3Cp%3EReturns true if %7B@code o%7D is in this Universe, false otherwise.%3C/p%3E%0A%09 * @param o the object to be tested for its presence in this Universe%0A%09 * @return true if %7B@code o%7D is in this Universe, false otherwise%0A%09 */%0A%09public boolean contains(Object o)%7B%0A%09%09return ei.containsKey(o);%0A%09%7D%0A%09%0A%09/**%0A%09 * %3Cp%3EReturns the number of elements that are a part of this Universe.%3C/p%3E%0A%09 * @return the number of elements in this Universe%0A%09 */
 %0A%09pu

document Universe class header and some methods