class DoublePointsToSet extends PointsToSetInternal {
  public DoublePointsToSet(Type type, PAG pag) {
    super(type);
    newSet = G.v().newSetFactory.newSet(type, pag);
    oldSet = G.v().oldSetFactory.newSet(type, pag);
    this.pag = pag;
  }

  /** Returns true if this set contains no run-time objects. */
  public boolean isEmpty() {
    return oldSet.isEmpty() && newSet.isEmpty();
  }

  /** Returns true if this set shares some objects with other. */
  public boolean hasNonEmptyIntersection(PointsToSet other) {
    return oldSet.hasNonEmptyIntersection(other) || newSet.hasNonEmptyIntersection(other);
  }

  /** Set of all possible run-time types of objects in the set. */
  public Set<Type> possibleTypes() {
    Set<Type> ret = new HashSet<Type>();
    ret.addAll(oldSet.possibleTypes());
    ret.addAll(newSet.possibleTypes());
    return ret;
  }

  /**
   * Adds contents of other into this set, returns true if this set changed.
   */
  public boolean addAll(PointsToSetInternal other, PointsToSetInternal exclude) {
    if (exclude != null) {
      throw new RuntimeException("NYI");
    }
    return newSet.addAll(other, oldSet);
  }

  /** Calls v's visit method on all nodes in this set. */
  public boolean forall(P2SetVisitor v) {
    oldSet.forall(v);
    newSet.forall(v);
    return v.getReturnValue();
  }

  /** Adds n to this set, returns true if n was not already in this set. */
  public boolean add(Node n) {
    if (oldSet.contains(n)) {
      return false;
    }
    return newSet.add(n);
  }

  /** Returns set of nodes already present before last call to flushNew. */
  public PointsToSetInternal getOldSet() {
    return oldSet;
  }

  /** Returns set of newly-added nodes since last call to flushNew. */
  public PointsToSetInternal getNewSet() {
    return newSet;
  }

  /** Sets all newly-added nodes to old nodes. */
  public void flushNew() {
    oldSet.addAll(newSet, null);
    newSet = G.v().newSetFactory.newSet(type, pag);
  }

  /** Sets all nodes to newly-added nodes. */
  public void unFlushNew() {
    newSet.addAll(oldSet, null);
    oldSet = G.v().oldSetFactory.newSet(type, pag);
  }

  /** Merges other into this set. */
  public void mergeWith(PointsToSetInternal other) {<FILL_FUNCTION_BODY>}

  /** Returns true iff the set contains n. */
  public boolean contains(Node n) {
    return oldSet.contains(n) || newSet.contains(n);
  }

  private static P2SetFactory defaultP2SetFactory = new P2SetFactory() {
    public PointsToSetInternal newSet(Type type, PAG pag) {
      return new DoublePointsToSet(type, pag);
    }
  };

  public static P2SetFactory getFactory(P2SetFactory newFactory, P2SetFactory oldFactory) {
    G.v().newSetFactory = newFactory;
    G.v().oldSetFactory = oldFactory;
    return defaultP2SetFactory;
  }

  /* End of public methods. */
  /* End of package methods. */

  private PAG pag;
  protected PointsToSetInternal newSet;
  protected PointsToSetInternal oldSet;
}

    if (!(other instanceof DoublePointsToSet)) {
      throw new RuntimeException("NYI");
    }
    final DoublePointsToSet o = (DoublePointsToSet) other;
    if ((other.type != null && !(other.type.equals(type))) || (other.type == null && type != null)) {
      throw new RuntimeException("different types " + type + " and " + other.type);
    }
    final PointsToSetInternal newNewSet = G.v().newSetFactory.newSet(type, pag);
    final PointsToSetInternal newOldSet = G.v().oldSetFactory.newSet(type, pag);
    oldSet.forall(new P2SetVisitor() {
      public final void visit(Node n) {
        if (o.oldSet.contains(n)) {
          newOldSet.add(n);
        }
      }
    });
    newNewSet.addAll(this, newOldSet);
    newNewSet.addAll(o, newOldSet);
    newSet = newNewSet;
    oldSet = newOldSet;
  
<methods>public void <init>(soot.Type) ,public abstract boolean add(soot.jimple.spark.pag.Node) ,public boolean addAll(soot.jimple.spark.sets.PointsToSetInternal, soot.jimple.spark.sets.PointsToSetInternal) ,public abstract boolean contains(soot.jimple.spark.pag.Node) ,public void flushNew() ,public abstract boolean forall(soot.jimple.spark.sets.P2SetVisitor) ,public soot.jimple.spark.sets.PointsToSetInternal getNewSet() ,public soot.jimple.spark.sets.PointsToSetInternal getOldSet() ,public soot.Type getType() ,public boolean hasNonEmptyIntersection(soot.PointsToSet) ,public void mergeWith(soot.jimple.spark.sets.PointsToSetInternal) ,public boolean pointsToSetEquals(java.lang.Object) ,public int pointsToSetHashCode() ,public Set<soot.jimple.ClassConstant> possibleClassConstants() ,public Set<java.lang.String> possibleStringConstants() ,public Set<soot.Type> possibleTypes() ,public void setType(soot.Type) ,public int size() ,public java.lang.String toString() ,public void unFlushNew() <variables>private static final org.slf4j.Logger logger,protected soot.Type type