// Path: Support/rsense-0.2/src/org/cx4a/rsense/ruby/IRubyObject.java
// public interface IRubyObject {
//     public Ruby getRuntime();
//     public RubyClass getMetaClass();
//     public void setMetaClass(RubyClass metaClass);
//     public RubyClass getSingletonClass();
//     public RubyClass makeMetaClass(RubyClass superClass);
//     public IRubyObject getInstVar(String name);
//     public void setInstVar(String name, IRubyObject value);
//     public boolean isNil();
//     public boolean isInstanceOf(RubyModule klass);
//     public boolean isKindOf(RubyModule klass);
//     public Object getTag();
//     public void setTag(Object tag);
// }
// 
// Path: Support/rsense-0.2/src/org/cx4a/rsense/typing/TypeSet.java
// public class TypeSet extends HashSet<IRubyObject> {
//     private static final long serialVersionUID = 0L;
//     public static final int MEGAMORPHIC_THRESHOLD = 5;
//     public static final TypeSet EMPTY = new TypeSet();
// 
//     private boolean megamorphic;
// 
//     public TypeSet() {
//         super();
//     }
// 
//     public TypeSet(TypeSet other) {
//         super(other);
//     }
// 
//     public boolean add(IRubyObject e) {
//         if (megamorphic) return false;
// 
//         if (size() >= MEGAMORPHIC_THRESHOLD) {
//             megamorphic = true;
//             // FIXME simple way
//             Logger.warn("megamorphic detected");
//             clear();
//             return super.add(new RubyObject(e.getRuntime(), e.getRuntime().getObject()));
//         } else {
//             return super.add(e);
//         }
//     }
// 
//     public boolean addAll(Collection<? extends IRubyObject> c) {
//         boolean changed = false;
//         for (IRubyObject e : c) {
//             if (add(e)) {
//                 changed = true;
//             }
//         }
//         return changed;
//     }
// 
//     public boolean isMegamorphic() {
//         return megamorphic;
//     }
// }
// 
// Path: Support/rsense-0.2/src/org/cx4a/rsense/typing/Propagation.java
// public class Propagation {
//     private Graph graph;
//     private Set<Object> visited;
//     private int refCount;
// 
//     public Propagation(Graph graph) {
//         this.graph = graph;
//         this.refCount = 0;
//     }
// 
//     public Graph getGraph() {
//         return graph;
//     }
// 
//     public boolean isVisited(Vertex vertex) {
//         return visited != null ? visited.contains(getVisitTag(vertex)) : false;
//     }
// 
//     public void addVisited(Vertex vertex) {
//         if (visited == null) {
//             // lazy allocation
//             visited = new HashSet<Object>();
//         }
//         visited.add(getVisitTag(vertex));
//     }
// 
//     public boolean checkVisited(Vertex vertex) {
//         if (isVisited(vertex)) {
//             return true;
//         } else {
//             addVisited(vertex);
//             return false;
//         }
//     }
// 
//     public void retain() {
//         refCount++;
//     }
// 
//     public boolean release() {
//         return --refCount == 0;
//     }
// 
//     private Object getVisitTag(Vertex vertex) {
//         return vertex.getNode() != null ? vertex.getNode() : vertex;
//     }
// }


import java.util.List;
import java.util.ArrayList;
import org.jruby.ast.Node;
import org.jruby.ast.FixnumNode;
import org.jruby.ast.StrNode;
import org.jruby.ast.SymbolNode;
import org.jruby.ast.types.INameNode;
import org.cx4a.rsense.ruby.IRubyObject;
import org.cx4a.rsense.typing.TypeSet;
import org.cx4a.rsense.typing.Propagation;
        return typeSet.isEmpty();
    }

    public void addType(IRubyObject type) {
        typeSet.add(type);
    }

    public void addTypeSet(TypeSet typeSet) {
        this.typeSet.addAll(typeSet);
    }
    
    public void copyTypeSet(Vertex other) {
        typeSet.addAll(other.getTypeSet());
    }

    public IRubyObject singleType() {
        if (typeSet.size() != 1) {
            return null;
        }
        return typeSet.iterator().next();
    }

    public void addEdge(Vertex dest) {
        edges.add(dest);
    }

    public void removeEdge(Vertex dest) {
        edges.remove(dest);
    }

// Path: Support/rsense-0.2/src/org/cx4a/rsense/ruby/IRubyObject.java
// public interface IRubyObject {
//     public Ruby getRuntime();
//     public RubyClass getMetaClass();
//     public void setMetaClass(RubyClass metaClass);
//     public RubyClass getSingletonClass();
//     public RubyClass makeMetaClass(RubyClass superClass);
//     public IRubyObject getInstVar(String name);
//     public void setInstVar(String name, IRubyObject value);
//     public boolean isNil();
//     public boolean isInstanceOf(RubyModule klass);
//     public boolean isKindOf(RubyModule klass);
//     public Object getTag();
//     public void setTag(Object tag);
// }
// 
// Path: Support/rsense-0.2/src/org/cx4a/rsense/typing/TypeSet.java
// public class TypeSet extends HashSet<IRubyObject> {
//     private static final long serialVersionUID = 0L;
//     public static final int MEGAMORPHIC_THRESHOLD = 5;
//     public static final TypeSet EMPTY = new TypeSet();
// 
//     private boolean megamorphic;
// 
//     public TypeSet() {
//         super();
//     }
// 
//     public TypeSet(TypeSet other) {
//         super(other);
//     }
// 
//     public boolean add(IRubyObject e) {
//         if (megamorphic) return false;
// 
//         if (size() >= MEGAMORPHIC_THRESHOLD) {
//             megamorphic = true;
//             // FIXME simple way
//             Logger.warn("megamorphic detected");
//             clear();
//             return super.add(new RubyObject(e.getRuntime(), e.getRuntime().getObject()));
//         } else {
//             return super.add(e);
//         }
//     }
// 
//     public boolean addAll(Collection<? extends IRubyObject> c) {
//         boolean changed = false;
//         for (IRubyObject e : c) {
//             if (add(e)) {
//                 changed = true;
//             }
//         }
//         return changed;
//     }
// 
//     public boolean isMegamorphic() {
//         return megamorphic;
//     }
// }
// 
// Path: Support/rsense-0.2/src/org/cx4a/rsense/typing/Propagation.java
// public class Propagation {
//     private Graph graph;
//     private Set<Object> visited;
//     private int refCount;
// 
//     public Propagation(Graph graph) {
//         this.graph = graph;
//         this.refCount = 0;
//     }
// 
//     public Graph getGraph() {
//         return graph;
//     }
// 
//     public boolean isVisited(Vertex vertex) {
//         return visited != null ? visited.contains(getVisitTag(vertex)) : false;
//     }
// 
//     public void addVisited(Vertex vertex) {
//         if (visited == null) {
//             // lazy allocation
//             visited = new HashSet<Object>();
//         }
//         visited.add(getVisitTag(vertex));
//     }
// 
//     public boolean checkVisited(Vertex vertex) {
//         if (isVisited(vertex)) {
//             return true;
//         } else {
//             addVisited(vertex);
//             return false;
//         }
//     }
// 
//     public void retain() {
//         refCount++;
//     }
// 
//     public boolean release() {
//         return --refCount == 0;
//     }
// 
//     private Object getVisitTag(Vertex vertex) {
//         return vertex.getNode() != null ? vertex.getNode() : vertex;
//     }
// }


// Path: Support/rsense-0.2/src/org/cx4a/rsense/typing/vertex/Vertex.java
import java.util.List;
import java.util.ArrayList;
import org.jruby.ast.Node;
import org.jruby.ast.FixnumNode;
import org.jruby.ast.StrNode;
import org.jruby.ast.SymbolNode;
import org.jruby.ast.types.INameNode;
import org.cx4a.rsense.ruby.IRubyObject;
import org.cx4a.rsense.typing.TypeSet;
import org.cx4a.rsense.typing.Propagation;

        return typeSet.isEmpty();
    }

    public void addType(IRubyObject type) {
        typeSet.add(type);
    }

    public void addTypeSet(TypeSet typeSet) {
        this.typeSet.addAll(typeSet);
    }
    
    public void copyTypeSet(Vertex other) {
        typeSet.addAll(other.getTypeSet());
    }

    public IRubyObject singleType() {
        if (typeSet.size() != 1) {
            return null;
        }
        return typeSet.iterator().next();
    }

    public void addEdge(Vertex dest) {
        edges.add(dest);
    }

    public void removeEdge(Vertex dest) {
        edges.remove(dest);
    }

    public boolean accept(Propagation propagation, Vertex src) {