class AndAggregator extends DepthFirstAdapter {

  public AndAggregator() {
  }

  public AndAggregator(boolean verbose) {
    super(verbose);
  }

  public void caseASTStatementSequenceNode(ASTStatementSequenceNode node) {
  }

  public void outASTIfNode(ASTIfNode node) {
    List<Object> bodies = node.get_SubBodies();
    if (bodies.size() == 1) { // this should always be one since there is
      // only one body of an if statement
      List body = (List) bodies.get(0);
      // this is the if body check to see if this is a single if Node
      if (body.size() == 1) {
        // size is good
        ASTNode bodyNode = (ASTNode) body.get(0);
        if (bodyNode instanceof ASTIfNode) {
          /*
           * We can do AndAggregation at this point node contains the outer if (ASTIfNode)bodyNode is the inner if
           */

          ASTCondition outerCond = node.get_Condition();
          ASTCondition innerCond = ((ASTIfNode) bodyNode).get_Condition();

          SETNodeLabel outerLabel = (node).get_Label();
          SETNodeLabel innerLabel = ((ASTIfNode) bodyNode).get_Label();

          SETNodeLabel newLabel = null;
          if (outerLabel.toString() == null && innerLabel.toString() == null) {
            newLabel = outerLabel;
          } else if (outerLabel.toString() != null && innerLabel.toString() == null) {
            newLabel = outerLabel;
          } else if (outerLabel.toString() == null && innerLabel.toString() != null) {
            newLabel = innerLabel;
          } else if (outerLabel.toString() != null && innerLabel.toString() != null) {
            newLabel = outerLabel;
            // however we have to change all occurance of inner
            // label to point to that
            // of outerlabel now
            changeUses(outerLabel.toString(), innerLabel.toString(), bodyNode);
          }

          // aggregate the conditions
          ASTCondition newCond = new ASTAndCondition(outerCond, innerCond);

          // Get the body of the inner Node that will be the overall
          // body
          List<Object> newBodyList = ((ASTIfNode) bodyNode).get_SubBodies();

          // retireve the actual body List
          if (newBodyList.size() == 1) {
            // should always be one since
            // this is body of IF
            List<Object> newBody = (List<Object>) newBodyList.get(0);
            node.replace(newLabel, newCond, newBody);
            // System.out.println("ANDDDDDD AGGREGATING !!!");
            G.v().ASTTransformations_modified = true;
          }
        } else {
          // not an if node
        }
      } else { // IfBody has more than 1 nodes cant do AND aggregation
      }
    }
  }

  private void changeUses(String to, String from, ASTNode node) {<FILL_FUNCTION_BODY>}

}

    // remember this method is only called when "to" and "from" are both non
    // null
    List<Object> subBodies = node.get_SubBodies();
    Iterator<Object> it = subBodies.iterator();
    while (it.hasNext()) {
      // going over all subBodies
      if (node instanceof ASTStatementSequenceNode) {
        // check for abrupt stmts

        ASTStatementSequenceNode stmtSeq = (ASTStatementSequenceNode) node;
        for (AugmentedStmt as : stmtSeq.getStatements()) {
          Stmt s = as.get_Stmt();

          if (s instanceof DAbruptStmt) {
            DAbruptStmt abStmt = (DAbruptStmt) s;
            if (abStmt.is_Break() || abStmt.is_Continue()) {
              SETNodeLabel label = abStmt.getLabel();
              String labelBroken = label.toString();

              if (labelBroken != null) {
                // stmt breaks some label
                if (labelBroken.compareTo(from) == 0) {
                  // have to replace the "from" label to "to"
                  // label
                  label.set_Name(to);
                }
              }
            }
          }
        }
      } else {
        // need to recursively call changeUses
        List subBodyNodes = null;

        if (node instanceof ASTTryNode) {
          ASTTryNode.container subBody = (ASTTryNode.container) it.next();
          subBodyNodes = (List) subBody.o;
        } else {
          subBodyNodes = (List) it.next();
        }
        Iterator nodesIt = subBodyNodes.iterator();
        while (nodesIt.hasNext()) {
          changeUses(to, from, (ASTNode) nodesIt.next());
        }
      }

    } // going through subBodies

  
<methods>public void <init>() ,public void <init>(boolean) ,public void caseASTAndCondition(soot.dava.internal.AST.ASTAndCondition) ,public void caseASTBinaryCondition(soot.dava.internal.AST.ASTBinaryCondition) ,public void caseASTDoWhileNode(soot.dava.internal.AST.ASTDoWhileNode) ,public void caseASTForLoopNode(soot.dava.internal.AST.ASTForLoopNode) ,public void caseASTIfElseNode(soot.dava.internal.AST.ASTIfElseNode) ,public void caseASTIfNode(soot.dava.internal.AST.ASTIfNode) ,public void caseASTLabeledBlockNode(soot.dava.internal.AST.ASTLabeledBlockNode) ,public void caseASTMethodNode(soot.dava.internal.AST.ASTMethodNode) ,public void caseASTOrCondition(soot.dava.internal.AST.ASTOrCondition) ,public void caseASTStatementSequenceNode(soot.dava.internal.AST.ASTStatementSequenceNode) ,public void caseASTSwitchNode(soot.dava.internal.AST.ASTSwitchNode) ,public void caseASTSynchronizedBlockNode(soot.dava.internal.AST.ASTSynchronizedBlockNode) ,public void caseASTTryNode(soot.dava.internal.AST.ASTTryNode) ,public void caseASTUnaryCondition(soot.dava.internal.AST.ASTUnaryCondition) ,public void caseASTUnconditionalLoopNode(soot.dava.internal.AST.ASTUnconditionalLoopNode) ,public void caseASTWhileNode(soot.dava.internal.AST.ASTWhileNode) ,public void caseArrayRef(soot.jimple.ArrayRef) ,public void caseBinopExpr(soot.jimple.BinopExpr) ,public void caseCastExpr(soot.jimple.CastExpr) ,public void caseDVariableDeclarationStmt(soot.dava.internal.javaRep.DVariableDeclarationStmt) ,public void caseDefinitionStmt(soot.jimple.DefinitionStmt) ,public void caseExpr(soot.jimple.Expr) ,public void caseExprOrRefValueBox(soot.ValueBox) ,public void caseInstanceFieldRef(soot.jimple.InstanceFieldRef) ,public void caseInstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) ,public void caseInstanceOfExpr(soot.jimple.InstanceOfExpr) ,public void caseInvokeExpr(soot.jimple.InvokeExpr) ,public void caseInvokeStmt(soot.jimple.InvokeStmt) ,public void caseNewArrayExpr(soot.jimple.NewArrayExpr) ,public void caseNewMultiArrayExpr(soot.jimple.NewMultiArrayExpr) ,public void caseRef(soot.jimple.Ref) ,public void caseReturnStmt(soot.jimple.ReturnStmt) ,public void caseStaticFieldRef(soot.jimple.StaticFieldRef) ,public void caseStmt(soot.jimple.Stmt) ,public void caseThrowStmt(soot.jimple.ThrowStmt) ,public void caseType(soot.Type) ,public void caseUnopExpr(soot.jimple.UnopExpr) ,public void caseValue(soot.Value) ,public void debug(java.lang.String, java.lang.String, java.lang.String) ,public void decideCaseExpr(soot.jimple.Expr) ,public void decideCaseExprOrRef(soot.Value) ,public void decideCaseRef(soot.jimple.Ref) ,public void inASTAndCondition(soot.dava.internal.AST.ASTAndCondition) ,public void inASTBinaryCondition(soot.dava.internal.AST.ASTBinaryCondition) ,public void inASTDoWhileNode(soot.dava.internal.AST.ASTDoWhileNode) ,public void inASTForLoopNode(soot.dava.internal.AST.ASTForLoopNode) ,public void inASTIfElseNode(soot.dava.internal.AST.ASTIfElseNode) ,public void inASTIfNode(soot.dava.internal.AST.ASTIfNode) ,public void inASTLabeledBlockNode(soot.dava.internal.AST.ASTLabeledBlockNode) ,public void inASTMethodNode(soot.dava.internal.AST.ASTMethodNode) ,public void inASTOrCondition(soot.dava.internal.AST.ASTOrCondition) ,public void inASTStatementSequenceNode(soot.dava.internal.AST.ASTStatementSequenceNode) ,public void inASTSwitchNode(soot.dava.internal.AST.ASTSwitchNode) ,public void inASTSynchronizedBlockNode(soot.dava.internal.AST.ASTSynchronizedBlockNode) ,public void inASTTryNode(soot.dava.internal.AST.ASTTryNode) ,public void inASTUnaryCondition(soot.dava.internal.AST.ASTUnaryCondition) ,public void inASTUnconditionalLoopNode(soot.dava.internal.AST.ASTUnconditionalLoopNode) ,public void inASTWhileNode(soot.dava.internal.AST.ASTWhileNode) ,public void inArrayRef(soot.jimple.ArrayRef) ,public void inBinopExpr(soot.jimple.BinopExpr) ,public void inCastExpr(soot.jimple.CastExpr) ,public void inDVariableDeclarationStmt(soot.dava.internal.javaRep.DVariableDeclarationStmt) ,public void inDefinitionStmt(soot.jimple.DefinitionStmt) ,public void inExpr(soot.jimple.Expr) ,public void inExprOrRefValueBox(soot.ValueBox) ,public void inInstanceFieldRef(soot.jimple.InstanceFieldRef) ,public void inInstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) ,public void inInstanceOfExpr(soot.jimple.InstanceOfExpr) ,public void inInvokeExpr(soot.jimple.InvokeExpr) ,public void inInvokeStmt(soot.jimple.InvokeStmt) ,public void inNewArrayExpr(soot.jimple.NewArrayExpr) ,public void inNewMultiArrayExpr(soot.jimple.NewMultiArrayExpr) ,public void inRef(soot.jimple.Ref) ,public void inReturnStmt(soot.jimple.ReturnStmt) ,public void inStaticFieldRef(soot.jimple.StaticFieldRef) ,public void inStmt(soot.jimple.Stmt) ,public void inThrowStmt(soot.jimple.ThrowStmt) ,public void inType(soot.Type) ,public void inUnopExpr(soot.jimple.UnopExpr) ,public void inValue(soot.Value) ,public void normalRetrieving(soot.dava.internal.AST.ASTNode) ,public void outASTAndCondition(soot.dava.internal.AST.ASTAndCondition) ,public void outASTBinaryCondition(soot.dava.internal.AST.ASTBinaryCondition) ,public void outASTDoWhileNode(soot.dava.internal.AST.ASTDoWhileNode) ,public void outASTForLoopNode(soot.dava.internal.AST.ASTForLoopNode) ,public void outASTIfElseNode(soot.dava.internal.AST.ASTIfElseNode) ,public void outASTIfNode(soot.dava.internal.AST.ASTIfNode) ,public void outASTLabeledBlockNode(soot.dava.internal.AST.ASTLabeledBlockNode) ,public void outASTMethodNode(soot.dava.internal.AST.ASTMethodNode) ,public void outASTOrCondition(soot.dava.internal.AST.ASTOrCondition) ,public void outASTStatementSequenceNode(soot.dava.internal.AST.ASTStatementSequenceNode) ,public void outASTSwitchNode(soot.dava.internal.AST.ASTSwitchNode) ,public void outASTSynchronizedBlockNode(soot.dava.internal.AST.ASTSynchronizedBlockNode) ,public void outASTTryNode(soot.dava.internal.AST.ASTTryNode) ,public void outASTUnaryCondition(soot.dava.internal.AST.ASTUnaryCondition) ,public void outASTUnconditionalLoopNode(soot.dava.internal.AST.ASTUnconditionalLoopNode) ,public void outASTWhileNode(soot.dava.internal.AST.ASTWhileNode) ,public void outArrayRef(soot.jimple.ArrayRef) ,public void outBinopExpr(soot.jimple.BinopExpr) ,public void outCastExpr(soot.jimple.CastExpr) ,public void outDVariableDeclarationStmt(soot.dava.internal.javaRep.DVariableDeclarationStmt) ,public void outDefinitionStmt(soot.jimple.DefinitionStmt) ,public void outExpr(soot.jimple.Expr) ,public void outExprOrRefValueBox(soot.ValueBox) ,public void outInstanceFieldRef(soot.jimple.InstanceFieldRef) ,public void outInstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) ,public void outInstanceOfExpr(soot.jimple.InstanceOfExpr) ,public void outInvokeExpr(soot.jimple.InvokeExpr) ,public void outInvokeStmt(soot.jimple.InvokeStmt) ,public void outNewArrayExpr(soot.jimple.NewArrayExpr) ,public void outNewMultiArrayExpr(soot.jimple.NewMultiArrayExpr) ,public void outRef(soot.jimple.Ref) ,public void outReturnStmt(soot.jimple.ReturnStmt) ,public void outStaticFieldRef(soot.jimple.StaticFieldRef) ,public void outStmt(soot.jimple.Stmt) ,public void outThrowStmt(soot.jimple.ThrowStmt) ,public void outType(soot.Type) ,public void outUnopExpr(soot.jimple.UnopExpr) ,public void outValue(soot.Value) <variables>public boolean DEBUG,boolean verbose