gt:         { // delete method foo, but copy if statement to goo
context: /*******************************************************************************
   * Copyright (c) 2000, 2009 IBM Corporation and others.
   * All rights reserved. This program and the accompanying materials
   * are made available under the terms of the Eclipse Public License v1.0
   * which accompanies this distribution, and is available at
   * http://www.eclipse.org/legal/epl-v10.html
   *
   * Contributors:
   *     IBM Corporation - initial API and implementation
   *******************************************************************************/
  package org.eclipse.che.ide.ext.java.client.core.rewrite;
  
  import org.eclipse.che.ide.ext.java.jdt.core.dom.AST;
  import org.eclipse.che.ide.ext.java.jdt.core.dom.ASTNode;
  import org.eclipse.che.ide.ext.java.jdt.core.dom.Block;
  import org.eclipse.che.ide.ext.java.jdt.core.dom.CastExpression;
  import org.eclipse.che.ide.ext.java.jdt.core.dom.CompilationUnit;
  import org.eclipse.che.ide.ext.java.jdt.core.dom.Expression;
  import org.eclipse.che.ide.ext.java.jdt.core.dom.ExpressionStatement;
  import org.eclipse.che.ide.ext.java.jdt.core.dom.ForStatement;
  import org.eclipse.che.ide.ext.java.jdt.core.dom.IfStatement;
  import org.eclipse.che.ide.ext.java.jdt.core.dom.MethodDeclaration;
  import org.eclipse.che.ide.ext.java.jdt.core.dom.MethodInvocation;
  import org.eclipse.che.ide.ext.java.jdt.core.dom.ParenthesizedExpression;
  import org.eclipse.che.ide.ext.java.jdt.core.dom.PrefixExpression;
  import org.eclipse.che.ide.ext.java.jdt.core.dom.ReturnStatement;
  import org.eclipse.che.ide.ext.java.jdt.core.dom.Statement;
  import org.eclipse.che.ide.ext.java.jdt.core.dom.Type;
  import org.eclipse.che.ide.ext.java.jdt.core.dom.TypeDeclaration;
  import org.eclipse.che.ide.ext.java.jdt.core.dom.VariableDeclarationFragment;
  import org.eclipse.che.ide.ext.java.jdt.core.dom.VariableDeclarationStatement;
  import org.eclipse.che.ide.ext.java.jdt.core.dom.WhileStatement;
  import org.eclipse.che.ide.ext.java.jdt.core.dom.rewrite.ASTRewrite;
  import org.eclipse.che.ide.ext.java.jdt.core.dom.rewrite.ListRewrite;
  import org.eclipse.che.ide.ext.java.jdt.internal.compiler.env.ICompilationUnit;
  
  import org.junit.Test;
  
  import java.util.List;
  
  import static org.junit.Assert.assertFalse;
  import static org.junit.Assert.assertTrue;
  
  public class ASTRewritingMoveCodeTest extends ASTRewritingTest {
  
      @Test
      public void testMove() throws Exception {
          StringBuffer buf = new StringBuffer();
          buf.append("package test1;\n");
          buf.append("public class E {\n");
          buf.append("    int x;\n");
          buf.append("    public void foo() {\n");
          buf.append("    }\n");
          buf.append("}\n");
          ICompilationUnit cu =
                  new org.eclipse.che.ide.ext.java.jdt.compiler.batch.CompilationUnit(buf.toString().toCharArray(), "E.java", "");
  
          CompilationUnit astRoot = createAST(cu);
          ASTRewrite rewrite = ASTRewrite.create(astRoot.getAST());
          assertTrue("Code has errors", (astRoot.getFlags() & ASTNode.MALFORMED) == 0);
  
          TypeDeclaration type = findTypeDeclaration(astRoot, "E");
          List bodyDecls = type.bodyDeclarations();
  
          ASTNode first = (ASTNode)bodyDecls.get(0);
          ASTNode placeholder = rewrite.createMoveTarget(first);
  
          rewrite.getListRewrite(type, TypeDeclaration.BODY_DECLARATIONS_PROPERTY).insertLast(placeholder, null);
  
          String preview = evaluateRewrite(cu, rewrite);
  
          buf = new StringBuffer();
          buf.append("package test1;\n");
          buf.append("public class E {\n");
          buf.append("    public void foo() {\n");
          buf.append("    }\n");
          buf.append("    int x;\n");
          buf.append("}\n");
          assertEqualString(preview, buf.toString());
  
      }
  
      @Test
      public void testMoveDeclSameLevelCD() throws Exception {
          StringBuffer buf = new StringBuffer();
          buf.append("package test1;\n");
          buf.append("public class E extends Exception implements Runnable, Serializable {\n");
          buf.append("    public static class EInner {\n");
          buf.append("        public void xee() {\n");
          buf.append("            /* does nothing */\n");
          buf.append("        }\n");
          buf.append("    }\n");
          buf.append("    private /* inner comment */ int i;\n");
          buf.append("    private int k;\n");
          buf.append("    public E() {\n");
          buf.append("        super();\n");
          buf.append("        i= 0;\n");
          buf.append("        k= 9;\n");
          buf.append("        if (System.out == null) {\n");
          buf.append("            gee(); // cool\n");
          buf.append("        }\n");
          buf.append("    }\n");
          buf.append("    public void gee() {\n");
          buf.append("    }\n");
          buf.append("}\n");
          buf.append("interface G {\n");
          buf.append("}\n");
          ICompilationUnit cu =
                  new org.eclipse.che.ide.ext.java.jdt.compiler.batch.CompilationUnit(buf.toString().toCharArray(), "E.java", "");
  
          CompilationUnit astRoot = createAST(cu);
          ASTRewrite rewrite = ASTRewrite.create(astRoot.getAST());
          assertTrue("Code has errors", (astRoot.getFlags() & ASTNode.MALFORMED) == 0);
  
          TypeDeclaration type = findTypeDeclaration(astRoot, "E");
  
          { // move inner type to the end of the type & move, copy statements from constructor to method
  
              List members = type.bodyDeclarations();
              assertTrue("Has declarations", !members.isEmpty());
  
              assertTrue("Cannot find inner class", members.get(0) instanceof TypeDeclaration);
              TypeDeclaration innerType = (TypeDeclaration)members.get(0);
  
              rewrite.remove(innerType, null);
              ASTNode movedNode = rewrite.createCopyTarget(innerType);
  
              rewrite.getListRewrite(type, TypeDeclaration.BODY_DECLARATIONS_PROPERTY).insertLast(movedNode, null);
  
              Statement toMove;
              Statement toCopy;
              {
                  MethodDeclaration methodDecl = findMethodDeclaration(type, "E");
                  assertTrue("Cannot find Constructor E", methodDecl != null);
                  Block body = methodDecl.getBody();
                  assertTrue("No body", body != null);
                  List statements = body.statements();
                  assertTrue("Not expected number of statements", statements.size() == 4);
  
                  toMove = (Statement)statements.get(1);
                  toCopy = (Statement)statements.get(3);
  
                  rewrite.remove(toMove, null);
              }
              {
                  MethodDeclaration methodDecl = findMethodDeclaration(type, "gee");
                  assertTrue("Cannot find gee()", methodDecl != null);
                  Block body = methodDecl.getBody();
                  assertTrue("No body", body != null);
                  List statements = body.statements();
                  assertTrue("Has statements", statements.isEmpty());
  
                  ASTNode insertNodeForMove = rewrite.createCopyTarget(toMove);
                  ASTNode insertNodeForCopy = rewrite.createCopyTarget(toCopy);
  
                  rewrite.getListRewrite(body, Block.STATEMENTS_PROPERTY).insertLast(insertNodeForCopy, null);
                  rewrite.getListRewrite(body, Block.STATEMENTS_PROPERTY).insertLast(insertNodeForMove, null);
  
              }
          }
  
          String preview = evaluateRewrite(cu, rewrite);
  
          buf = new StringBuffer();
          buf.append("package test1;\n");
          buf.append("public class E extends Exception implements Runnable, Serializable {\n");
          buf.append("    private /* inner comment */ int i;\n");
          buf.append("    private int k;\n");
          buf.append("    public E() {\n");
          buf.append("        super();\n");
          buf.append("        k= 9;\n");
          buf.append("        if (System.out == null) {\n");
          buf.append("            gee(); // cool\n");
          buf.append("        }\n");
          buf.append("    }\n");
          buf.append("    public void gee() {\n");
          buf.append("        if (System.out == null) {\n");
          buf.append("            gee(); // cool\n");
          buf.append("        }\n");
          buf.append("        i= 0;\n");
          buf.append("    }\n");
          buf.append("    public static class EInner {\n");
          buf.append("        public void xee() {\n");
          buf.append("            /* does nothing */\n");
          buf.append("        }\n");
          buf.append("    }\n");
          buf.append("}\n");
          buf.append("interface G {\n");
          buf.append("}\n");
          assertEqualString(preview, buf.toString());
  
      }
  
      @Test
      public void testMoveDeclSameLevel() throws Exception {
          StringBuffer buf = new StringBuffer();
          buf.append("package test1;\n");
          buf.append("public class E extends Exception implements Runnable, Serializable {\n");
          buf.append("    public static class EInner {\n");
          buf.append("        public void xee() {\n");
          buf.append("            /* does nothing */\n");
          buf.append("        }\n");
          buf.append("    }\n");
          buf.append("    private /* inner comment */ int i;\n");
          buf.append("    private int k;\n");
          buf.append("    public E() {\n");
          buf.append("        super();\n");
          buf.append("        i= 0;\n");
          buf.append("        k= 9;\n");
          buf.append("        if (System.out == null) {\n");
          buf.append("            gee(); // cool\n");
          buf.append("        }\n");
          buf.append("    }\n");
          buf.append("    public void gee() {\n");
          buf.append("    }\n");
          buf.append("}\n");
          buf.append("interface G {\n");
          buf.append("}\n");
          ICompilationUnit cu =
                  new org.eclipse.che.ide.ext.java.jdt.compiler.batch.CompilationUnit(buf.toString().toCharArray(), "E.java", "");
  
          CompilationUnit astRoot = createAST(cu);
          ASTRewrite rewrite = ASTRewrite.create(astRoot.getAST());
          assertTrue("Code has errors", (astRoot.getFlags() & ASTNode.MALFORMED) == 0);
  
          TypeDeclaration type = findTypeDeclaration(astRoot, "E");
  
          { // move inner type to the end of the type & move, copy statements from constructor to method
  
              List members = type.bodyDeclarations();
              assertTrue("Has declarations", !members.isEmpty());
  
              assertTrue("Cannot find inner class", members.get(0) instanceof TypeDeclaration);
              TypeDeclaration innerType = (TypeDeclaration)members.get(0);
  
              ASTNode movedNode = rewrite.createMoveTarget(innerType);
              rewrite.getListRewrite(type, TypeDeclaration.BODY_DECLARATIONS_PROPERTY).insertLast(movedNode, null);
  
              Statement toMove;
              Statement toCopy;
              {
                  MethodDeclaration methodDecl = findMethodDeclaration(type, "E");
                  assertTrue("Cannot find Constructor E", methodDecl != null);
                  Block body = methodDecl.getBody();
                  assertTrue("No body", body != null);
                  List statements = body.statements();
                  assertTrue("Not expected number of statements", statements.size() == 4);
  
                  toMove = (Statement)statements.get(1);
                  toCopy = (Statement)statements.get(3);
              }
              {
                  MethodDeclaration methodDecl = findMethodDeclaration(type, "gee");
                  assertTrue("Cannot find gee()", methodDecl != null);
                  Block body = methodDecl.getBody();
                  assertTrue("No body", body != null);
                  List statements = body.statements();
                  assertTrue("Has statements", statements.isEmpty());
  
                  ASTNode insertNodeForMove = rewrite.createMoveTarget(toMove);
                  ASTNode insertNodeForCopy = rewrite.createCopyTarget(toCopy);
  
                  rewrite.getListRewrite(body, Block.STATEMENTS_PROPERTY).insertLast(insertNodeForCopy, null);
                  rewrite.getListRewrite(body, Block.STATEMENTS_PROPERTY).insertLast(insertNodeForMove, null);
              }
          }
  
          String preview = evaluateRewrite(cu, rewrite);
  
          buf = new StringBuffer();
          buf.append("package test1;\n");
          buf.append("public class E extends Exception implements Runnable, Serializable {\n");
          buf.append("    private /* inner comment */ int i;\n");
          buf.append("    private int k;\n");
          buf.append("    public E() {\n");
          buf.append("        super();\n");
          buf.append("        k= 9;\n");
          buf.append("        if (System.out == null) {\n");
          buf.append("            gee(); // cool\n");
          buf.append("        }\n");
          buf.append("    }\n");
          buf.append("    public void gee() {\n");
          buf.append("        if (System.out == null) {\n");
          buf.append("            gee(); // cool\n");
          buf.append("        }\n");
          buf.append("        i= 0;\n");
          buf.append("    }\n");
          buf.append("    public static class EInner {\n");
          buf.append("        public void xee() {\n");
          buf.append("            /* does nothing */\n");
          buf.append("        }\n");
          buf.append("    }\n");
          buf.append("}\n");
          buf.append("interface G {\n");
          buf.append("}\n");
          assertEqualString(preview, buf.toString());
  
      }
  
      @Test
      public void testMoveDeclDifferentLevelCD() throws Exception {
          StringBuffer buf = new StringBuffer();
          buf.append("package test1;\n");
          buf.append("public class E extends Exception implements Runnable, Serializable {\n");
          buf.append("    public static class EInner {\n");
          buf.append("        public void xee() {\n");
          buf.append("            /* does nothing */\n");
          buf.append("        }\n");
          buf.append("    }\n");
          buf.append("    private /* inner comment */ int i;\n");
          buf.append("    private int k;\n");
          buf.append("    public E() {\n");
          buf.append("        super();\n");
          buf.append("        i= 0;\n");
          buf.append("        k= 9;\n");
          buf.append("        if (System.out == null) {\n");
          buf.append("            gee(); // cool\n");
          buf.append("        }\n");
          buf.append("    }\n");
          buf.append("    public void gee() {\n");
          buf.append("    }\n");
          buf.append("}\n");
          buf.append("interface G {\n");
          buf.append("}\n");
          ICompilationUnit cu =
                  new org.eclipse.che.ide.ext.java.jdt.compiler.batch.CompilationUnit(buf.toString().toCharArray(), "E.java", "");
  
          CompilationUnit astRoot = createAST(cu);
          ASTRewrite rewrite = ASTRewrite.create(astRoot.getAST());
          AST ast = astRoot.getAST();
          assertTrue("Code has errors", (astRoot.getFlags() & ASTNode.MALFORMED) == 0);
  
          TypeDeclaration type = findTypeDeclaration(astRoot, "E");
  
          {
              List members = type.bodyDeclarations();
              assertTrue("Has declarations", !members.isEmpty());
  
              assertTrue("Cannot find inner class", members.get(0) instanceof TypeDeclaration);
              TypeDeclaration innerType = (TypeDeclaration)members.get(0);
  
              List innerMembers = innerType.bodyDeclarations();
              assertTrue("Not expected number of inner members", innerMembers.size() == 1);
  
              { // move outer as inner of inner.
                  TypeDeclaration outerType = findTypeDeclaration(astRoot, "G");
                  assertTrue("G not found", outerType != null);
  
                  rewrite.remove(outerType, null);
  
                  ASTNode insertNodeForCopy = rewrite.createCopyTarget(outerType);
  
                  rewrite.getListRewrite(innerType, TypeDeclaration.BODY_DECLARATIONS_PROPERTY).insertLast(insertNodeForCopy,
                                                                                                           null);
  
              }
              { // copy method of inner to main type
                  MethodDeclaration methodDecl = (MethodDeclaration)innerMembers.get(0);
                  ASTNode insertNodeForMove = rewrite.createCopyTarget(methodDecl);
  
                  rewrite.getListRewrite(type, TypeDeclaration.BODY_DECLARATIONS_PROPERTY)
                         .insertLast(insertNodeForMove, null);
  
              }
              { // nest body of constructor in a while statement
                  MethodDeclaration methodDecl = findMethodDeclaration(type, "E");
                  assertTrue("Cannot find Constructor E", methodDecl != null);
  
                  Block body = methodDecl.getBody();
  
                  WhileStatement whileStatement = ast.newWhileStatement();
                  whileStatement.setExpression(ast.newBooleanLiteral(true));
  
                  Statement insertNodeForCopy = (Statement)rewrite.createCopyTarget(body);
  
                  whileStatement.setBody(insertNodeForCopy); // set existing body
  
                  Block newBody = ast.newBlock();
                  List newStatements = newBody.statements();
                  newStatements.add(whileStatement);
  
                  rewrite.replace(body, newBody, null);
              }
          }
  
          String preview = evaluateRewrite(cu, rewrite);
  
          buf = new StringBuffer();
          buf.append("package test1;\n");
          buf.append("public class E extends Exception implements Runnable, Serializable {\n");
          buf.append("    public static class EInner {\n");
          buf.append("        public void xee() {\n");
          buf.append("            /* does nothing */\n");
          buf.append("        }\n");
          buf.append("\n");
          buf.append("        interface G {\n");
          buf.append("        }\n");
          buf.append("    }\n");
          buf.append("    private /* inner comment */ int i;\n");
          buf.append("    private int k;\n");
          buf.append("    public E() {\n");
          buf.append("        while (true) {\n");
          buf.append("            super();\n");
          buf.append("            i= 0;\n");
          buf.append("            k= 9;\n");
          buf.append("            if (System.out == null) {\n");
          buf.append("                gee(); // cool\n");
          buf.append("            }\n");
          buf.append("        }\n");
          buf.append("    }\n");
          buf.append("    public void gee() {\n");
          buf.append("    }\n");
          buf.append("    public void xee() {\n");
          buf.append("        /* does nothing */\n");
          buf.append("    }\n");
          buf.append("}\n");
          assertEqualString(preview, buf.toString());
  
      }
  
      @Test
      public void testMoveDeclDifferentLevel() throws Exception {
          StringBuffer buf = new StringBuffer();
          buf.append("package test1;\n");
          buf.append("public class E extends Exception implements Runnable, Serializable {\n");
          buf.append("    public static class EInner {\n");
          buf.append("        public void xee() {\n");
          buf.append("            /* does nothing */\n");
          buf.append("        }\n");
          buf.append("    }\n");
          buf.append("    private /* inner comment */ int i;\n");
          buf.append("    private int k;\n");
          buf.append("    public E() {\n");
          buf.append("        super();\n");
          buf.append("        i= 0;\n");
          buf.append("        k= 9;\n");
          buf.append("        if (System.out == null) {\n");
          buf.append("            gee(); // cool\n");
          buf.append("        }\n");
          buf.append("    }\n");
          buf.append("    public void gee() {\n");
          buf.append("    }\n");
          buf.append("}\n");
          buf.append("interface G {\n");
          buf.append("}\n");
          ICompilationUnit cu =
                  new org.eclipse.che.ide.ext.java.jdt.compiler.batch.CompilationUnit(buf.toString().toCharArray(), "E.java", "");
  
          CompilationUnit astRoot = createAST(cu);
          ASTRewrite rewrite = ASTRewrite.create(astRoot.getAST());
          AST ast = astRoot.getAST();
          assertTrue("Code has errors", (astRoot.getFlags() & ASTNode.MALFORMED) == 0);
  
          TypeDeclaration type = findTypeDeclaration(astRoot, "E");
  
          {
              List members = type.bodyDeclarations();
              assertTrue("Has declarations", !members.isEmpty());
  
              assertTrue("Cannot find inner class", members.get(0) instanceof TypeDeclaration);
              TypeDeclaration innerType = (TypeDeclaration)members.get(0);
  
              List innerMembers = innerType.bodyDeclarations();
              assertTrue("Not expected number of inner members", innerMembers.size() == 1);
  
              { // move outer as inner of inner.
                  TypeDeclaration outerType = findTypeDeclaration(astRoot, "G");
                  assertTrue("G not found", outerType != null);
  
                  ASTNode insertNodeForCopy = rewrite.createMoveTarget(outerType);
  
                  rewrite.getListRewrite(innerType, TypeDeclaration.BODY_DECLARATIONS_PROPERTY).insertLast(insertNodeForCopy,
                                                                                                           null);
              }
              { // copy method of inner to main type
                  MethodDeclaration methodDecl = (MethodDeclaration)innerMembers.get(0);
                  ASTNode insertNodeForMove = rewrite.createCopyTarget(methodDecl);
  
                  rewrite.getListRewrite(type, TypeDeclaration.BODY_DECLARATIONS_PROPERTY)
                         .insertLast(insertNodeForMove, null);
              }
              { // nest body of constructor in a while statement
                  MethodDeclaration methodDecl = findMethodDeclaration(type, "E");
                  assertTrue("Cannot find Constructor E", methodDecl != null);
  
                  Block body = methodDecl.getBody();
  
                  WhileStatement whileStatement = ast.newWhileStatement();
                  whileStatement.setExpression(ast.newBooleanLiteral(true));
  
                  Statement insertNodeForCopy = (Statement)rewrite.createCopyTarget(body);
  
                  whileStatement.setBody(insertNodeForCopy); // set existing body
  
                  Block newBody = ast.newBlock();
                  List newStatements = newBody.statements();
                  newStatements.add(whileStatement);
  
                  rewrite.replace(body, newBody, null);
              }
          }
  
          String preview = evaluateRewrite(cu, rewrite);
  
          buf = new StringBuffer();
          buf.append("package test1;\n");
          buf.append("public class E extends Exception implements Runnable, Serializable {\n");
          buf.append("    public static class EInner {\n");
          buf.append("        public void xee() {\n");
          buf.append("            /* does nothing */\n");
          buf.append("        }\n");
          buf.append("\n");
          buf.append("        interface G {\n");
          buf.append("        }\n");
          buf.append("    }\n");
          buf.append("    private /* inner comment */ int i;\n");
          buf.append("    private int k;\n");
          buf.append("    public E() {\n");
          buf.append("        while (true) {\n");
          buf.append("            super();\n");
          buf.append("            i= 0;\n");
          buf.append("            k= 9;\n");
          buf.append("            if (System.out == null) {\n");
          buf.append("                gee(); // cool\n");
          buf.append("            }\n");
          buf.append("        }\n");
          buf.append("    }\n");
          buf.append("    public void gee() {\n");
          buf.append("    }\n");
          buf.append("    public void xee() {\n");
          buf.append("        /* does nothing */\n");
          buf.append("    }\n");
          buf.append("}\n");
          assertEqualString(preview, buf.toString());
  
      }
  
      @Test
      public void testMoveStatementsCD() throws Exception {
          StringBuffer buf = new StringBuffer();
          buf.append("package test1;\n");
          buf.append("public class E extends Exception implements Runnable, Serializable {\n");
          buf.append("    public static class EInner {\n");
          buf.append("        public void xee() {\n");
          buf.append("            /* does nothing */\n");
          buf.append("        }\n");
          buf.append("    }\n");
          buf.append("    private /* inner comment */ int i;\n");
          buf.append("    private int k;\n");
          buf.append("    public E() {\n");
          buf.append("        super();\n");
          buf.append("        i= 0;\n");
          buf.append("        k= 9;\n");
          buf.append("        if (System.out == null) {\n");
          buf.append("            gee(); // cool\n");
          buf.append("        }\n");
          buf.append("    }\n");
          buf.append("    public void gee() {\n");
          buf.append("    }\n");
          buf.append("}\n");
          buf.append("interface G {\n");
          buf.append("}\n");
          ICompilationUnit cu =
                  new org.eclipse.che.ide.ext.java.jdt.compiler.batch.CompilationUnit(buf.toString().toCharArray(), "E.java", "");
  
          CompilationUnit astRoot = createAST(cu);
          ASTRewrite rewrite = ASTRewrite.create(astRoot.getAST());
          AST ast = astRoot.getAST();
          assertTrue("Code has errors", (astRoot.getFlags() & ASTNode.MALFORMED) == 0);
  
          TypeDeclaration type = findTypeDeclaration(astRoot, "E");
  
          { // move first statments inside an ifstatement, move second statment inside a new while statement
              // that is in the ifstatement
              MethodDeclaration methodDecl = findMethodDeclaration(type, "E");
              assertTrue("Cannot find Constructor E", methodDecl != null);
  
              Block body = methodDecl.getBody();
              List statements = body.statements();
  
              assertTrue("Cannot find if statement", statements.get(3) instanceof IfStatement);
  
              IfStatement ifStatement = (IfStatement)statements.get(3);
  
              Statement insertNodeForCopy1 = (Statement)rewrite.createCopyTarget((ASTNode)statements.get(1));
              Statement insertNodeForCopy2 = (Statement)rewrite.createCopyTarget((ASTNode)statements.get(2));
  
              Block whileBody = ast.newBlock();
  
              WhileStatement whileStatement = ast.newWhileStatement();
              whileStatement.setExpression(ast.newBooleanLiteral(true));
              whileStatement.setBody(whileBody);
  
              List whileBodyStatements = whileBody.statements();
              whileBodyStatements.add(insertNodeForCopy2);
  
              assertTrue("if statement body not a block", ifStatement.getThenStatement() instanceof Block);
  
              Block block = (Block)ifStatement.getThenStatement();
  
              rewrite.getListRewrite(block, Block.STATEMENTS_PROPERTY).insertFirst(whileStatement, null);
              rewrite.getListRewrite(block, Block.STATEMENTS_PROPERTY).insertAfter(insertNodeForCopy1, whileStatement, null);
  
              rewrite.remove((ASTNode)statements.get(1), null);
              rewrite.remove((ASTNode)statements.get(2), null);
          }
  
          String preview = evaluateRewrite(cu, rewrite);
  
          buf = new StringBuffer();
          buf.append("package test1;\n");
          buf.append("public class E extends Exception implements Runnable, Serializable {\n");
          buf.append("    public static class EInner {\n");
          buf.append("        public void xee() {\n");
          buf.append("            /* does nothing */\n");
          buf.append("        }\n");
          buf.append("    }\n");
          buf.append("    private /* inner comment */ int i;\n");
          buf.append("    private int k;\n");
          buf.append("    public E() {\n");
          buf.append("        super();\n");
          buf.append("        if (System.out == null) {\n");
          buf.append("            while (true) {\n");
          buf.append("                k= 9;\n");
          buf.append("            }\n");
          buf.append("            i= 0;\n");
          buf.append("            gee(); // cool\n");
          buf.append("        }\n");
          buf.append("    }\n");
          buf.append("    public void gee() {\n");
          buf.append("    }\n");
          buf.append("}\n");
          buf.append("interface G {\n");
          buf.append("}\n");
          assertEqualString(preview, buf.toString());
  
      }
  
      @Test
      public void testMoveStatements() throws Exception {
          StringBuffer buf = new StringBuffer();
          buf.append("package test1;\n");
          buf.append("public class E extends Exception implements Runnable, Serializable {\n");
          buf.append("    private /* inner comment */ int i;\n");
          buf.append("    private int k;\n");
          buf.append("    public E() {\n");
          buf.append("        super();\n");
          buf.append("        i= 0;\n");
          buf.append("        k= 9;\n");
          buf.append("        if (System.out == null) {\n");
          buf.append("            gee(); // cool\n");
          buf.append("        }\n");
          buf.append("    }\n");
          buf.append("    public void gee() {\n");
          buf.append("    }\n");
          buf.append("}\n");
          buf.append("interface G {\n");
          buf.append("}\n");
          ICompilationUnit cu =
                  new org.eclipse.che.ide.ext.java.jdt.compiler.batch.CompilationUnit(buf.toString().toCharArray(), "E.java", "");
  
          CompilationUnit astRoot = createAST(cu);
          ASTRewrite rewrite = ASTRewrite.create(astRoot.getAST());
          AST ast = astRoot.getAST();
          assertTrue("Code has errors", (astRoot.getFlags() & ASTNode.MALFORMED) == 0);
  
          TypeDeclaration type = findTypeDeclaration(astRoot, "E");
  
          { // move first statments inside an ifstatement, move second statment inside a new while statement
              // that is in the ifstatement
              MethodDeclaration methodDecl = findMethodDeclaration(type, "E");
              assertTrue("Cannot find Constructor E", methodDecl != null);
  
              Block body = methodDecl.getBody();
              List statements = body.statements();
  
              assertTrue("Cannot find if statement", statements.get(3) instanceof IfStatement);
  
              IfStatement ifStatement = (IfStatement)statements.get(3);
  
              Statement insertNodeForCopy1 = (Statement)rewrite.createMoveTarget((ASTNode)statements.get(1));
              Statement insertNodeForCopy2 = (Statement)rewrite.createMoveTarget((ASTNode)statements.get(2));
  
              Block whileBody = ast.newBlock();
  
              WhileStatement whileStatement = ast.newWhileStatement();
              whileStatement.setExpression(ast.newBooleanLiteral(true));
              whileStatement.setBody(whileBody);
  
              List whileBodyStatements = whileBody.statements();
              whileBodyStatements.add(insertNodeForCopy2);
  
              assertTrue("if statement body not a block", ifStatement.getThenStatement() instanceof Block);
  
              Block block = (Block)ifStatement.getThenStatement();
              rewrite.getListRewrite(block, Block.STATEMENTS_PROPERTY).insertFirst(whileStatement, null);
              rewrite.getListRewrite(block, Block.STATEMENTS_PROPERTY).insertAfter(insertNodeForCopy1, whileStatement, null);
          }
  
          String preview = evaluateRewrite(cu, rewrite);
  
          buf = new StringBuffer();
          buf.append("package test1;\n");
          buf.append("public class E extends Exception implements Runnable, Serializable {\n");
          buf.append("    private /* inner comment */ int i;\n");
          buf.append("    private int k;\n");
          buf.append("    public E() {\n");
          buf.append("        super();\n");
          buf.append("        if (System.out == null) {\n");
          buf.append("            while (true) {\n");
          buf.append("                k= 9;\n");
          buf.append("            }\n");
          buf.append("            i= 0;\n");
          buf.append("            gee(); // cool\n");
          buf.append("        }\n");
          buf.append("    }\n");
          buf.append("    public void gee() {\n");
          buf.append("    }\n");
          buf.append("}\n");
          buf.append("interface G {\n");
          buf.append("}\n");
          assertEqualString(preview, buf.toString());
  
      }
  
      @Test
      public void testCopyFromDeleted() throws Exception {
          StringBuffer buf = new StringBuffer();
          buf.append("package test1;\n");
          buf.append("public class E {\n");
          buf.append("    public void foo() {\n");
          buf.append("        if (System.out == null) {\n");
          buf.append("            gee(); // cool\n");
          buf.append("        }\n");
          buf.append("    }\n");
          buf.append("    public void goo() {\n");
          buf.append("    }\n");
          buf.append("}\n");
          ICompilationUnit cu =
                  new org.eclipse.che.ide.ext.java.jdt.compiler.batch.CompilationUnit(buf.toString().toCharArray(), "E.java", "");
  
          CompilationUnit astRoot = createAST(cu);
          ASTRewrite rewrite = ASTRewrite.create(astRoot.getAST());
          assertTrue("Code has errors", (astRoot.getFlags() & ASTNode.MALFORMED) == 0);
  
          TypeDeclaration type = findTypeDeclaration(astRoot, "E");
  
  