protected boolean addTarget(int pc, CGNode tNode) {
   allTargets.add(getCallGraph().getNumber(tNode));
   Object S = targets.get(pc);
   if (S == null) {
     S = tNode;
     targets.set(pc, S);
     getCallGraph().addEdge(this, tNode);
     return true;
   } else {
     if (S instanceof CGNode) {
       if (S.equals(tNode)) {
         return false;
       } else {
         MutableSharedBitVectorIntSet s = new MutableSharedBitVectorIntSet();
         s.add(getCallGraph().getNumber((CGNode) S));
         s.add(getCallGraph().getNumber(tNode));
         getCallGraph().addEdge(this, tNode);
         targets.set(pc, s);
         return true;
       }
     } else {
       MutableIntSet s = (MutableIntSet) S;
       int n = getCallGraph().getNumber(tNode);
       if (!s.contains(n)) {
         s.add(n);
         getCallGraph().addEdge(this, tNode);
         return true;
       } else {
         return false;
       }
     }
   }
 }
 /*
  * @see com.ibm.wala.ipa.callgraph.impl.BasicCallGraph.NodeImpl#removeTarget(com.ibm.wala.ipa.callgraph.CGNode)
  */
 public void removeTarget(CGNode target) {
   allTargets.remove(getCallGraph().getNumber(target));
   for (IntIterator it = targets.safeIterateIndices(); it.hasNext(); ) {
     int pc = it.next();
     Object value = targets.get(pc);
     if (value instanceof CGNode) {
       if (value.equals(target)) {
         targets.remove(pc);
       }
     } else {
       MutableIntSet s = (MutableIntSet) value;
       int n = getCallGraph().getNumber(target);
       if (s.size() > 2) {
         s.remove(n);
       } else {
         assert s.size() == 2;
         if (s.contains(n)) {
           s.remove(n);
           int i = s.intIterator().next();
           targets.set(pc, getCallGraph().getNode(i));
         }
       }
     }
   }
 }
  @SuppressWarnings("unused")
  private boolean loopsAreSimple(
      ControlFlowGraph<SSAInstruction, ISSABasicBlock> cfg, Set<ISSABasicBlock> scc)
      throws CancelException {
    boolean isSimple = true;

    MutableIntSet sccInts = MutableSparseIntSet.createMutableSparseIntSet(scc.size());
    for (ISSABasicBlock bb : scc) {
      sccInts.add(cfg.getNumber(bb));
    }

    boolean noExit = true;

    for (ISSABasicBlock bb : scc) {
      if (cfg.getSuccNodeCount(bb) > 1 && !cfg.getSuccNodeNumbers(bb).isSubset(sccInts)) {
        noExit = false;
        // if preds are no subset of the scc block we have a jump to the outside of the scc
        SSAInstruction last = bb.getLastInstruction();
        int[] uses = new int[last.getNumberOfUses()];

        for (int i = 0; i < uses.length; i++) {
          uses[i] = last.getUse(i);
        }

        TransitiveDataDependence tdep = new TransitiveDataDependence(scc);
        tdep.solve(null);

        for (ISSABasicBlock bb2 : scc) {
          if (bb2 == bb) {
            continue;
          }

          for (SSAInstruction ii : bb2) {
            for (int use : uses) {
              isSimple &= !tdep.influences(ii, use);
            }

            //						IntSet is = tdep.influences((SSAInstruction) ii);
            //						System.err.println(ii + ": " + is);

            if (!isSimple) {
              break;
            }
          }

          if (!isSimple) {
            break;
          }
        }

        // TODO check if condition is simple...
        //				if (isSimple) {
        //					System.err.println("Simple: " + last + " -> " +
        // PrettyWalaNames.methodName(bb.getMethod()));
        //				} else {
        //					System.err.println("Not Simple: " + last + " -> " +
        // PrettyWalaNames.methodName(bb.getMethod()));
        //				}

        if (!isSimple) {
          break;
        }
      }
    }

    return isSimple && !noExit;
  }