@@ -0,0 +1,2477 @@
+package exm.parser.ic;%0A%0Aimport java.util.ArrayList;%0Aimport java.util.Collection;%0Aimport java.util.Collections;%0Aimport java.util.HashMap;%0Aimport java.util.LinkedList;%0Aimport java.util.List;%0Aimport java.util.Map.Entry;%0Aimport java.util.Set;%0A%0A/**%0A * Simple multi-map implementation that is useful for%0A * some algorithms.  Lists are used to store values in order.%0A * %0A * The list is implemented as an ArrayList by default, but a factory%0A * can be provided that produces other list types.%0A *%0A * @param %3CK%3E%0A * @param %3CV%3E%0A */%0Apublic class MultiMap%3CK, V%3E %7B%0A%0A  public MultiMap() %7B%0A    this(new ArrayListFactory%3CV%3E());%0A  %7D%0A  %0A  public MultiMap(ListFactory%3CV%3E f) %7B%0A    this.factory = f;%0A  %7D%0A  %0A  private final ListFactory%3CV%3E factory;%0A%0A  private HashMap%3CK, List%3CV%3E%3E map = %0A        new HashMap%3CK, List%3CV%3E%3E(); %0A  %0A  /**%0A   * Returns the value associated with a key.%0A   * The list is allowed to be mutated and changes will%0A   * be reflected in the map%0A   * @param key%0A   * @return a list (never null - empty list if no keys!)%0A   */%0A  public List%3CV%3E get(K key) %7B%0A    List%3CV%3E val = map.get(key);%0A    if (val == null) %7B%0A      return Collections.emptyList();%0A    %7D else %7B%0A      return val;%0A    %7D%0A  %7D%0A  %0A  public Set%3CEntry%3CK, List%3CV%3E%3E%3E entrySet() %7B%0A    return map.entrySet();%0A  %7D%0A%0A  public Set%3CK%3E keySet() %7B%0A    return map.keySet();%0A  %7D%0A%0A  public Collection%3CList%3CV%3E%3E values() %7B%0A    return map.values();%0A  %7D%0A%0A  public void put(K key, V val) %7B%0A    List%3CV%3E list = map.get(key);%0A    if (list == null) %7B%0A      list = factory.make();%0A      map.put(key, list);%0A    %7D%0A    list.add(val);%0A  %7D%0A%0A  public boolean containsKey(K key) %7B%0A    return map.containsKey(key) %0A            && map.get(key).size() %3E 0;%0A  %7D%0A%0A  public List%3CV%3E remove(Object key) %7B%0A    return map.remove(key);%0A  %7D%0A%0A  /**%0A   * Can't tell always if definitely empty, since it is%0A   * possible that a caller mutated one of the lists and%0A   * made it empty.  This will be correct if remove() is called%0A   * whenever a stored list has all its elements removed%0A   * @return%0A   */%0A  public boolean isDefinitelyEmpty() %7B%0A    return map.isEmpty();%0A  %7D%0A  %0A  %0A  public static interface ListFactory%3CV1%3E %7B%0A    public List%3CV1%3E make();%0A  %7D%0A  %0A  public static class LinkedListFactory%3CV1%3E %0A            implements ListFactory%3CV1%3E %7B%0A    public List%3CV1%3E make() %7B%0A      return new LinkedList%3CV1%3E();%0A    %7D%0A  %7D%0A  %0A  public static class ArrayListFactory%3CV1%3E %0A  implements ListFactory%3CV1%3E %7B%0A    public List%3CV1%3E make() %7B%0A      return new ArrayList%3CV1%3E();%0A    %7D%0A  %7D%0A%7D%0A

Add missing class