class TryContentsFinder extends ASTAnalysis {
  public TryContentsFinder(Singletons.Global g) {
  }

  public static TryContentsFinder v() {
    return G.v().soot_dava_toolkits_base_AST_TryContentsFinder();
  }

  private IterableSet curExceptionSet = new IterableSet();
  private final HashMap<Object, IterableSet> node2ExceptionSet = new HashMap<Object, IterableSet>();

  public int getAnalysisDepth() {
    return ANALYSE_VALUES;
  }

  public IterableSet remove_CurExceptionSet() {
    IterableSet s = curExceptionSet;

    set_CurExceptionSet(new IterableSet());

    return s;
  }

  public void set_CurExceptionSet(IterableSet curExceptionSet) {
    this.curExceptionSet = curExceptionSet;
  }

  public void analyseThrowStmt(ThrowStmt s) {
    Value op = (s).getOp();

    if (op instanceof Local) {
      add_ThrownType(((Local) op).getType());
    } else if (op instanceof FieldRef) {
      add_ThrownType(((FieldRef) op).getType());
    }
  }

  private void add_ThrownType(Type t) {
    if (t instanceof RefType) {
      curExceptionSet.add(((RefType) t).getSootClass());
    }
  }

  public void analyseInvokeExpr(InvokeExpr ie) {
    curExceptionSet.addAll(ie.getMethod().getExceptions());
  }

  public void analyseInstanceInvokeExpr(InstanceInvokeExpr iie) {
    analyseInvokeExpr(iie);
  }

  public void analyseASTNode(ASTNode n) {
    if (n instanceof ASTTryNode) {

      ASTTryNode tryNode = (ASTTryNode) n;

      ArrayList<Object> toRemove = new ArrayList<Object>();
      IterableSet tryExceptionSet = node2ExceptionSet.get(tryNode.get_TryBodyContainer());
      if (tryExceptionSet == null) {
        tryExceptionSet = new IterableSet();
        node2ExceptionSet.put(tryNode.get_TryBodyContainer(), tryExceptionSet);
      }

      List<Object> catchBodies = tryNode.get_CatchList();
      List<Object> subBodies = tryNode.get_SubBodies();

      Iterator<Object> cit = catchBodies.iterator();
      while (cit.hasNext()) {
        Object catchBody = cit.next();
        SootClass exception = (SootClass) tryNode.get_ExceptionMap().get(catchBody);

        if (!catches_Exception(tryExceptionSet, exception) && !catches_RuntimeException(exception)) {
          toRemove.add(catchBody);
        }
      }

      Iterator<Object> trit = toRemove.iterator();
      while (trit.hasNext()) {
        Object catchBody = trit.next();

        subBodies.remove(catchBody);
        catchBodies.remove(catchBody);
      }

      IterableSet passingSet = (IterableSet) tryExceptionSet.clone();
      cit = catchBodies.iterator();
      while (cit.hasNext()) {
        passingSet.remove(tryNode.get_ExceptionMap().get(cit.next()));
      }

      cit = catchBodies.iterator();
      while (cit.hasNext()) {
        passingSet.addAll(get_ExceptionSet(cit.next()));
      }

      node2ExceptionSet.put(n, passingSet);
    }

    else {
      Iterator<Object> sbit = n.get_SubBodies().iterator();
      while (sbit.hasNext()) {
        Iterator it = ((List) sbit.next()).iterator();
        while (it.hasNext()) {
          add_ExceptionSet(n, get_ExceptionSet(it.next()));
        }
      }
    }

    remove_CurExceptionSet();
  }

  public IterableSet get_ExceptionSet(Object node) {
    IterableSet fullSet = node2ExceptionSet.get(node);
    if (fullSet == null) {
      fullSet = new IterableSet();
      node2ExceptionSet.put(node, fullSet);
    }

    return fullSet;
  }

  public void add_ExceptionSet(Object node, IterableSet s) {<FILL_FUNCTION_BODY>}

  private boolean catches_Exception(IterableSet tryExceptionSet, SootClass c) {
    Iterator it = tryExceptionSet.iterator();
    while (it.hasNext()) {
      SootClass thrownException = (SootClass) it.next();

      while (true) {
        if (thrownException == c) {
          return true;
        }

        if (!thrownException.hasSuperclass()) {
          break;
        }

        thrownException = thrownException.getSuperclass();
      }
    }

    return false;
  }

  private boolean catches_RuntimeException(SootClass c) {
    if ((c == Scene.v().getSootClass("java.lang.Throwable")) || (c == Scene.v().getSootClass("java.lang.Exception"))) {
      return true;
    }

    SootClass caughtException = c, runtimeException = Scene.v().getSootClass("java.lang.RuntimeException");

    while (true) {
      if (caughtException == runtimeException) {
        return true;
      }

      if (!caughtException.hasSuperclass()) {
        return false;
      }

      caughtException = caughtException.getSuperclass();
    }
  }
}

    IterableSet fullSet = node2ExceptionSet.get(node);
    if (fullSet == null) {
      fullSet = new IterableSet();
      node2ExceptionSet.put(node, fullSet);
    }

    fullSet.addAll(s);
  
<methods>public non-sealed void <init>() ,public void analyseASTNode(soot.dava.internal.AST.ASTNode) ,public void analyseArrayRef(soot.jimple.ArrayRef) ,public void analyseBinopExpr(soot.jimple.BinopExpr) ,public void analyseDefinitionStmt(soot.jimple.DefinitionStmt) ,public void analyseExpr(soot.jimple.Expr) ,public void analyseInstanceFieldRef(soot.jimple.InstanceFieldRef) ,public void analyseInstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) ,public void analyseInstanceOfExpr(soot.jimple.InstanceOfExpr) ,public void analyseInvokeExpr(soot.jimple.InvokeExpr) ,public void analyseInvokeStmt(soot.jimple.InvokeStmt) ,public void analyseNewArrayExpr(soot.jimple.NewArrayExpr) ,public void analyseNewMultiArrayExpr(soot.jimple.NewMultiArrayExpr) ,public void analyseRef(soot.jimple.Ref) ,public void analyseReturnStmt(soot.jimple.ReturnStmt) ,public void analyseStmt(soot.jimple.Stmt) ,public void analyseThrowStmt(soot.jimple.ThrowStmt) ,public void analyseUnopExpr(soot.jimple.UnopExpr) ,public void analyseValue(soot.Value) ,public abstract int getAnalysisDepth() <variables>public static final int ANALYSE_AST,public static final int ANALYSE_STMTS,public static final int ANALYSE_VALUES