package ciir.jfoley.chai.collections;

import java.util.*;

/**
 * For when you want the intersection or something but you don't actually care about speed. O(n) contains etc., but original add order is preserved.
 * @author jfoley
 */
@SuppressWarnings({"NullableProblems", "SuspiciousToArrayCall"})
public class ListBasedOrderedSet<T> implements Set<T> {
  public final List<T> list;

  public ListBasedOrderedSet() {
    this.list = new ArrayList<>();
  }

  /**
   * When you're constructing from an existing collection.
   * @param ts the collection to start from.
   */
  public ListBasedOrderedSet(Collection<? extends T> ts) {
    this();
    this.addAll(ts);
  }

  public List<T> toList() {
    return list;
  }

  @Override
  public Iterator<T> iterator() {
    return list.iterator();
  }

  @Override
  public Object[] toArray() {
    return list.toArray();
  }

  @Override
  public <T1> T1[] toArray(T1[] t1s) {
    return list.toArray(t1s);
  }

  @Override
  public boolean add(T pred) {
    for (T already : list) {
      if(already.equals(pred)) {
        return false;
      }
    }
    list.add(pred);
    return true;
  }

  @Override
  public boolean remove(Object o) {
    return list.remove(o);
  }

  @Override
  public boolean containsAll(Collection<?> objects) {
    return list.containsAll(objects);
  }

  @Override
  public boolean addAll(Collection<? extends T> ts) {
    boolean changed = false;
    for (T t : ts) {
      changed |= this.add(t);
    }
    return changed;
  }

  @Override
  public boolean retainAll(Collection<?> objects) {
    return list.retainAll(objects);
  }

  @Override
  public boolean removeAll(Collection<?> objects) {
    return list.removeAll(objects);
  }

  @Override
  public void clear() {
    list.clear();
  }

  @Override
  public int size() {
    return list.size();
  }

  @Override
  public boolean isEmpty() {
    return list.isEmpty();
  }

  @Override
  public boolean contains(Object o) {
    return list.contains(o);
  }
}

@@ -32,16 +32,49 @@
 tions;%0A%0A
+import javax.annotation.Nonnull;%0A
 import j
@@ -265,73 +265,8 @@
  */%0A
-@SuppressWarnings(%7B%22NullableProblems%22, %22SuspiciousToArrayCall%22%7D)%0A
 publ
@@ -301,19 +301,24 @@
 %3CT%3E 
-implement
+extend
 s 
+Abstract
 Set%3C
@@ -692,32 +692,43 @@
  %7D%0A%0A  @Override%0A
+  @Nonnull%0A
   public Iterato
@@ -782,168 +782,8 @@
  %7D%0A%0A
-  @Override%0A  public Object%5B%5D toArray() %7B%0A    return list.toArray();%0A  %7D%0A%0A  @Override%0A  public %3CT1%3E T1%5B%5D toArray(T1%5B%5D t1s) %7B%0A    return list.toArray(t1s);%0A  %7D%0A%0A
   @O
@@ -1078,24 +1078,33 @@
 containsAll(
+@Nonnull 
 Collection%3C?
@@ -1191,24 +1191,33 @@
 lean addAll(
+@Nonnull 
 Collection%3C?
@@ -1349,218 +1349,8 @@
  %7D%0A%0A
-  @Override%0A  public boolean retainAll(Collection%3C?%3E objects) %7B%0A    return list.retainAll(objects);%0A  %7D%0A%0A  @Override%0A  public boolean removeAll(Collection%3C?%3E objects) %7B%0A    return list.removeAll(objects);%0A  %7D%0A%0A
   @O

Use AbstractSet instead of implements Set so we get .equals and .hashCode too; also fix ``@Nullable`` warnings