_____________________________________________________________________________
 Immediately
 
+  - Performance
+
+     - Next target: TopologicalBag (make it wickedfast: preoptimize)
+
+     - Forest: keep() and valid() -- can we do this with states
+       rather than subtrees?
+
+     - hash Long->long: it's all bogus
+
+  * huge performance improvement (try for more)
+  * pick back up cleaning up end of Parser.java (Reduction)
+  * some weird edge cases; check last regression test, 'make doc'
+
+
   - Sensible tree-printout
   - make Tib.Block extend Tree<>
 
 
                 if (token==null) break;
                 int count = 0;
                 Parser.Table.Reduction r = null;
-                for(Parser.Table.Reduction red : token==null ? state.getEofReductions() : state.getReductions(token)) { r = red; count++; }
-                if (count==0) return;     // BEWARE! this optimization is suspected to cause really nasty heisenbugs
+                if (!state.hasReductions(token)) return;
                 //if (count > 1) break;
                 //if (r.numPop == 0) break;
                 //r.reduce(pending, parent, null, Phase.this, null);
             private Node(Node parent, Forest pending, Parser.Table.State state, Phase start) {
                 this.state = state;
                 if (pending != null) this.holder().merge(pending);
-                if (parent != null) parents().add(parent, true);
+                if (parent != null) parents().add(parent);
                 if (Phase.this.hash.get(code(state, start)) != null) throw new Error("severe problem!");
                 Phase.this.hash.put(code(state, start), this);
                 Phase.this.numNodes++;
 
             public Iterable<State>     getShifts(Token t)          { return shifts.get(t); }
             public boolean             isAccepting()               { return accept; }
             public Iterable<Reduction> getReductions(Token t)      { return t==null ? eofReductions : reductions.get(t); }
+            public boolean             hasReductions(Token t)      { return t==null ? eofReductions.size()>0 : reductions.has(t); }
             public Iterable<Reduction> getEofReductions()          { return eofReductions; }
             public Iterator<Position>  iterator()                  { return hs.iterator(); }
 
 
 
 public /*final*/ class FastSet<T> implements Iterator<T>, Iterable<T> {
 
-    public static final int INITIAL_SIZE = 128;
+    public static final int INITIAL_SIZE = 8;
 
-    private       Object[] array;
+    private       Object[] array = null;
     private       T        only  = null;
     private       int      i     = -1;
     private       int      size  = 0;
         }
     }
     public void add(T t, boolean check) {
-        if (check) for(Object o : this) if (o.equals(t)) return;
+        //if (check) for(Object o : this) if (o.equals(t)) return;
+        if (check) for(Object o : this) if (o==t) return;
         add(t);
     }
     public void add(T t) {
 
         return false;
     }
 
+    public boolean has(K k) {
+        for(Topology<K> t : h.keySet())
+            if (t.contains(k) && !h.get(t).isEmpty())
+                return true;
+        return false;
+    }
+
     private HashMap<K,Iterable<V>> cache = new HashMap<K,Iterable<V>>();
     public Iterable<V> getAll(Topology<K> k) { return h.get(k); }
     public Iterable<V> get(K k) {