!include #1001196 // Lisp

static class AList<A> implements Iterable<A> {
  new L<A> data; // don't access this from outside
  
  // these are ok to access (but not change) from outside
  final S id = randomID(8);
  final L<Lisp> history = synchroList();
  
  public synchronized void add(A a) {
    data.add(a);
    history.add(lisp("add", structure(a)));
  }
  
  public synchronized void clear() {
    data.clear();
    history.add(lisp("clear"));
  }
  
  public synchronized void remove(int i) {
    data.remove(i);
    history.add(lisp("remove", "" + i));
  }
  
  public synchronized void remove(A a) {
    int i = data.indexOf(a);
    if (i >= 0) remove(i);
  }
  
  public synchronized int indexOf(A a) {
    return data.indexOf(a);
  }
  
  public synchronized A get(int i) {
    return data.get(i);
  }
  
  public S getID() {
    return id;
  }
  
  public synchronized int size() {
    return data.size();
  }
  
  public synchronized Iterator<A> iterator() {
    ret new ArrayList<A>(data).iterator();
  }
  
  public synchronized List<A> shoot() {
    ret new ArrayList<A>(data);
  }
}