/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.netbeans.modules.refactoring.java.test;

import org.netbeans.modules.java.source.parsing.JavacParser;
import org.netbeans.modules.refactoring.api.Problem;
import org.netbeans.modules.refactoring.java.api.JavaMoveMembersProperties.Visibility;

/**
 *
 * @author Ralph Ruijs
 */
public class MoveMethodTest extends MoveBase {

    private static String SOURCE_LEVEL = "1.8"; //NOI18N

    public MoveMethodTest(String name) {
        super(name, SOURCE_LEVEL);
    }
    
    static {
        JavacParser.DISABLE_SOURCE_LEVEL_DOWNGRADE = true;
    }
    public void test236877() throws Exception {
        writeFilesAndWaitForScan(src,
                new File("t/SourceClass.java", "package t;\n"
                + "public class SourceClass {\n"
                + "    public void movedMethod(SourceClass a) {\n"
                + "    }\n"
                + "}\n"),
                new File("u/TargetClass.java", "package u;\n"
                + "public class TargetClass {\n"
                + "}\n"));
        performMove(src.getFileObject("t/SourceClass.java"), new int[]{1}, src.getFileObject("u/TargetClass.java"), Visibility.PUBLIC, false);
        verifyContent(src,
                new File("t/SourceClass.java", "package t;\n"
                + "public class SourceClass {\n"
                + "}\n"),
                new File("u/TargetClass.java", "package u;\n"
                + "import t.SourceClass;\n"
                + "public class TargetClass {\n"
                + "    public void movedMethod(SourceClass a) {\n"
                + "    }\n"
                + "}\n"));
    }
    
    public void testMoveComments() throws Exception {
        writeFilesAndWaitForScan(src,
                new File("t/A.java", "package t;\n"
                        + "public class A {\n"
                        + "    public void doStuff() {\n"
                        + "        // do stuff dude!\n"
                        + "        //more stuff\n"
                        + "        int i = 2 + 2;\n"
                        + "        assert i == 4;\n"
                        + "        // more stuff\n"
                        + "        // do stuff dude!\n"
                        + "        //more stuff\n"
                        + "        i = 2 + 2;\n"
                        + "        assert i == 4;\n"
                        + "        // more stuff\n"
                        + "        // do stuff dude!\n"
                        + "        //more stuff\n"
                        + "        i = 2 + 2;\n"
                        + "        assert i == 4;\n"
                        + "        // more stuff\n"
                        + "        // do stuff dude!\n"
                        + "        //more stuff\n"
                        + "        i = 2 + 2;\n"
                        + "        assert i == 4;\n"
                        + "        // more stuff\n"
                        + "        // do stuff dude!\n"
                        + "        //more stuff\n"
                        + "        i = 2 + 2;\n"
                        + "        assert i == 4;\n"
                        + "        // more stuff\n"
                        + "    }\n"
                        + "}\n"),
                new File("t/B.java", "package t;\n"
                + "public class B {\n"
                + "}\n"));
        performMove(src.getFileObject("t/A.java"), new int[]{1}, src.getFileObject("t/B.java"), Visibility.PUBLIC, false);
        verifyContent(src,
                new File("t/A.java", "package t;\n"
                + "public class A {\n"
                + "}\n"),
                new File("t/B.java", "package t;\n"
                + "public class B {\n"
                + "    public void doStuff() {\n"
                + "        // do stuff dude!\n"
                + "        //more stuff\n"
                + "        int i = 2 + 2;\n"
                + "        assert i == 4;\n"
                + "        // more stuff\n"
                + "        // do stuff dude!\n"
                + "        //more stuff\n"
                + "        i = 2 + 2;\n"
                + "        assert i == 4;\n"
                + "        // more stuff\n"
                + "        // do stuff dude!\n"
                + "        //more stuff\n"
                + "        i = 2 + 2;\n"
                + "        assert i == 4;\n"
                + "        // more stuff\n"
                + "        // do stuff dude!\n"
                + "        //more stuff\n"
                + "        i = 2 + 2;\n"
                + "        assert i == 4;\n"
                + "        // more stuff\n"
                + "        // do stuff dude!\n"
                + "        //more stuff\n"
                + "        i = 2 + 2;\n"
                + "        assert i == 4;\n"
                + "        // more stuff\n"
                + "    }\n"
                + "}\n"));
    }
    
    public void testMoveGenericReturn() throws Exception {
        writeFilesAndWaitForScan(src,
                new File("t/A.java", "package t;\n"
                + "import java.util.List;\n"
                + "public class A {\n"
                + "    /** Something about i */\n"
                + "    List<String> i() { return null; }\n"
                + "    public void foo() {\n"
                + "        B b = new B();\n"
                + "        System.out.println(i());\n"
                + "    }\n"
                + "}\n"),
                new File("t/B.java", "package t;\n"
                + "public class B {\n"
                + "    public void foo() {\n"
                + "        A a = new A();\n"
                + "        System.out.println(a.i());\n"
                + "    }\n"
                + "}\n"));
        performMove(src.getFileObject("t/A.java"), new int[]{1}, src.getFileObject("t/B.java"), Visibility.PUBLIC, false);
        verifyContent(src,
                new File("t/A.java", "package t;\n"
                + "import java.util.List;\n"
                + "public class A {\n"
                + "    public void foo() {\n"
                + "        B b = new B();\n"
                + "        System.out.println(b.i());\n"
                + "    }\n"
                + "}\n"),
                new File("t/B.java", "package t;\n"
                + "import java.util.List;\n"
                + "public class B {\n"
                + "    public void foo() {\n"
                + "        A a = new A();\n"
                + "        System.out.println(i());\n"
                + "    }\n"
                + "    /** Something about i */\n"
                + "    public List<String> i() { return null; }\n"
                + "}\n"));
    }
    
    public void testMoveKeepOld() throws Exception {
        writeFilesAndWaitForScan(src,
                new File("t/A.java", "package t;\n"
                + "public class A {\n"
                + "    public static String param = \"a\";\n"
                + "    \n"
                + "    public static void movedMethod(String p) {\n"
                + "        \n"
                + "    }\n"
                + "    \n"
                + "    public void test() {\n"
                + "        movedMethod(param);\n"
                + "    }\n"
                + "}\n"),
                new File("t/B.java", "package t;\n"
                + "public class B {\n"
                + "}\n"));
        performMove(src.getFileObject("t/A.java"), new int[]{2}, src.getFileObject("t/B.java"), Visibility.ASIS, false);
        verifyContent(src,
                new File("t/A.java", "package t;\n"
                + "public class A {\n"
                + "    public static String param = \"a\";\n"
                + "    \n"
                + "    public void test() {\n"
                + "        B.movedMethod(param);\n"
                + "    }\n"
                + "}\n"),
                new File("t/B.java", "package t;\n"
                + "public class B {\n"
                + "    \n"
                + "    public static void movedMethod(String p) {\n"
                + "        \n"
                + "    }\n"
                + "}\n"));
    }
    
    public void test232604() throws Exception {
        writeFilesAndWaitForScan(src,
                new File("t/A.java", "package t;\n"
                + "public class A {\n"
                + "    /** Something about i */\n"
                + "    int i(D d, B b) { return b.b; }\n"
                + "    public void foo() {\n"
                + "        B b = new B();\n"
                + "        System.out.println(i(null, new B()));\n"
                + "    }\n"
                + "}\n"),
                new File("t/B.java", "package t;\n"
                + "public class B {\n"
                + "    public int b = 5;\n"
                + "    public void foo() {\n"
                + "        A a = new A();\n"
                + "        System.out.println(a.i(null, this));\n"
                + "    }\n"
                + "}\n"),
                new File("t/C.java", "package t;\n"
                + "public class C {\n"
                + "    public void foo() {\n"
                + "        A a = new A();\n"
                + "        B b = new B();\n"
                + "        System.out.println(a.i(null, b));\n"
                + "    }\n"
                + "}\n"));
        performMove(src.getFileObject("t/A.java"), new int[]{1}, src.getFileObject("t/B.java"), Visibility.PUBLIC, false);
        verifyContent(src,
                new File("t/A.java", "package t;\n"
                + "public class A {\n"
                + "    public void foo() {\n"
                + "        B b = new B();\n"
                + "        System.out.println(new B().i(null));\n"
                + "    }\n"
                + "}\n"),
                new File("t/B.java", "package t;\n"
                + "public class B {\n"
                + "    public int b = 5;\n"
                + "    public void foo() {\n"
                + "        A a = new A();\n"
                + "        System.out.println(i(null));\n"
                + "    }\n"
                + "    /** Something about i */\n"
                + "    public int i(D d) { return this.b; }\n"
                + "}\n"),
                new File("t/C.java", "package t;\n"
                + "public class C {\n"
                + "    public void foo() {\n"
                + "        A a = new A();\n"
                + "        B b = new B();\n"
                + "        System.out.println(b.i(null));\n"
                + "    }\n"
                + "}\n"));
    }

    public void test232902() throws Exception {
        writeFilesAndWaitForScan(src,
                new File("t/A.java", "package t;\n"
                + "public class A {\n"
                + "\n"
                + "    private void instanceMethod() {\n"
                + "    }\n"
                + "\n"
                + "    public void usage(InnerTarget ic) throws IOException {\n"
                + "        instanceMethod();\n"
                + "    }\n"
                + "\n"
                + "    public class InnerTarget {\n"
                + "\n"
                + "    }\n"
                + "}\n"));
        performMove(src.getFileObject("t/A.java"), new int[]{2}, "t.A.InnerTarget", Visibility.ESCALATE);
        verifyContent(src,
                new File("t/A.java", "package t;\n"
                + "public class A {\n"
                + "\n"
                + "    public void usage(InnerTarget ic) throws IOException {\n"
                + "        ic.instanceMethod();\n"
                + "    }\n"
                + "\n"
                + "    public class InnerTarget {\n"
                + "\n"
                + "    private void instanceMethod() {\n"
                + "    }\n"
                + "\n"
                + "    }\n"
                + "}\n"));
    }
    
    public void test222403() throws Exception {
        writeFilesAndWaitForScan(src,
                new File("t/A.java", "package t;\n"
                + "public class A {\n"
                + "    public Runnable create() {\n"
                + "        return new Runnable() {\n"
                + "            public void run() {\n"
                + "            }\n"
                + "        };\n"
                + "    }\n"
                + "}\n"),
                new File("t/B.java", "package t;\n"
                + "public class B {\n"
                + "}\n"));
        performMove(src.getFileObject("t/A.java"), new int[]{1}, src.getFileObject("t/B.java"), Visibility.PUBLIC, false);
        verifyContent(src,
                new File("t/A.java", "package t;\n"
                + "public class A {\n"
                + "}\n"),
                new File("t/B.java", "package t;\n"
                + "public class B {\n"
                + "    public Runnable create() {\n"
                + "        return new Runnable() {\n"
                + "            public void run() {\n"
                + "            }\n"
                + "        };\n"
                + "    }\n"
                + "}\n"));
    }
    
    public void test215809() throws Exception {
        writeFilesAndWaitForScan(src,
                new File("t/A.java", "package t;\n"
                + "public class A {\n"
                + "    /** Something about i */\n"
                + "    int i() { return 1; }\n"
                + "    public void foo() {\n"
                + "        B b = new B();\n"
                + "        System.out.println(i());\n"
                + "    }\n"
                + "}\n"),
                new File("t/B.java", "package t;\n"
                + "public class B {\n"
                + "    /** Something about i */\n"
                + "    int i(boolean j) { return 2; }\n"
                + "    public void foo() {\n"
                + "        A a = new A();\n"
                + "        System.out.println(a.i());\n"
                + "    }\n"
                + "}\n"),
                new File("t/C.java", "package t;\n"
                + "public class C {\n"
                + "    public void foo() {\n"
                + "        A a = new A();\n"
                + "        B b = new B();\n"
                + "        System.out.println(a.i());\n"
                + "    }\n"
                + "}\n"));
        performMove(src.getFileObject("t/A.java"), new int[]{1}, src.getFileObject("t/B.java"), Visibility.PUBLIC, false);
        verifyContent(src,
                new File("t/A.java", "package t;\n"
                + "public class A {\n"
                + "    public void foo() {\n"
                + "        B b = new B();\n"
                + "        System.out.println(b.i());\n"
                + "    }\n"
                + "}\n"),
                new File("t/B.java", "package t;\n"
                + "public class B {\n"
                + "    /** Something about i */\n"
                + "    int i(boolean j) { return 2; }\n"
                + "    public void foo() {\n"
                + "        A a = new A();\n"
                + "        System.out.println(i());\n"
                + "    }\n"
                + "    /** Something about i */\n"
                + "    public int i() { return 1; }\n"
                + "}\n"),
                new File("t/C.java", "package t;\n"
                + "public class C {\n"
                + "    public void foo() {\n"
                + "        A a = new A();\n"
                + "        B b = new B();\n"
                + "        System.out.println(b.i());\n"
                + "    }\n"
                + "}\n"));
    }
    
    public void testMoveAbstractPolymorphic() throws Exception {
        writeFilesAndWaitForScan(src,
                new File("t/A.java", "package t;\n"
                + "public class A {\n"
                + "    public void foo() {\n"
                + "        System.out.println(i());\n"
                + "    }\n"
                + "    public abstract void bar();\n"
                + "}\n"),
                new File("t/B.java", "package t;\n"
                + "public class B extends A {\n"
                + "    public void foo() {\n"
                + "        System.out.println(j());\n"
                + "    }\n"
                + "}\n"),
                new File("t/C.java", "package t;\n"
                + "public interface C {\n"
                + "    void doo();"
                + "}\n"));
        performMove(src.getFileObject("t/A.java"), new int[]{1}, src.getFileObject("t/C.java"), Visibility.PUBLIC, false, new Problem(true, "ERR_MoveMethodPolymorphic"));
        performMove(src.getFileObject("t/A.java"), new int[]{2}, src.getFileObject("t/C.java"), Visibility.PUBLIC, false, new Problem(true, "ERR_MoveAbstractMember"));
        performMove(src.getFileObject("t/C.java"), new int[]{0}, src.getFileObject("t/A.java"), Visibility.PUBLIC, false, new Problem(true, "ERR_MoveFromClass"));
    }

    public void test209620() throws Exception {
        writeFilesAndWaitForScan(src,
                new File("t/SourceClass.java", "package t;\n"
                + "public class SourceClass {\n"
                + "    static int field;\n"
                + "\n"
                + "    public void movedMethod() {\n"
                + "        if(field==1) field++;\n"
                + "        java.util.Random r = new java.util.Random(field);\n"
                + "        field = r.nextInt();\n"
                + "    }\n"
                + "\n"
                + "    public void usage() {\n"
                + "        TargetClass tClass = new TargetClass();\n"
                + "        t.SourceClass.this.movedMethod();\n"
                + "    }\n"
                + "}\n"),
                new File("t/TargetClass.java", "package t;\n"
                + "public class TargetClass {\n"
                + "}\n"));
        performMove(src.getFileObject("t/SourceClass.java"), new int[]{}, null, Visibility.ASIS, false, new Problem(true, "ERR_NothingSelected"));
        verifyContent(src,
                new File("t/SourceClass.java", "package t;\n"
                + "public class SourceClass {\n"
                + "    static int field;\n"
                + "\n"
                + "    public void movedMethod() {\n"
                + "        if(field==1) field++;\n"
                + "        java.util.Random r = new java.util.Random(field);\n"
                + "        field = r.nextInt();\n"
                + "    }\n"
                + "\n"
                + "    public void usage() {\n"
                + "        TargetClass tClass = new TargetClass();\n"
                + "        t.SourceClass.this.movedMethod();\n"
                + "    }\n"
                + "}\n"),
                new File("t/TargetClass.java", "package t;\n"
                + "public class TargetClass {\n"
                + "}\n"));
    }

    public void test207833() throws Exception {
        writeFilesAndWaitForScan(src,
                new File("t/SourceClass.java", "package t;\n"
                + "public class SourceClass {\n"
                + "    static int field;\n"
                + "\n"
                + "    public void movedMethod() {\n"
                + "        if(field==1) field++;\n"
                + "        java.util.Random r = new java.util.Random(field);\n"
                + "        field = r.nextInt();\n"
                + "    }\n"
                + "\n"
                + "    public void usage() {\n"
                + "        TargetClass tClass = new TargetClass();\n"
                + "        t.SourceClass.this.movedMethod();\n"
                + "    }\n"
                + "}\n"),
                new File("t/TargetClass.java", "package t;\n"
                + "public class TargetClass {\n"
                + "}\n"));
        performMove(src.getFileObject("t/SourceClass.java"), new int[]{2}, src.getFileObject("t/TargetClass.java"), Visibility.PUBLIC, false);
        verifyContent(src,
                new File("t/SourceClass.java", "package t;\n"
                + "public class SourceClass {\n"
                + "    static int field;\n"
                + "\n"
                + "    public void usage() {\n"
                + "        TargetClass tClass = new TargetClass();\n"
                + "        tClass.movedMethod();\n"
                + "    }\n"
                + "}\n"),
                new File("t/TargetClass.java", "package t;\n"
                + "import java.util.Random;\n"
                + "public class TargetClass {\n"
                + "    public void movedMethod() {\n"
                + "        if (SourceClass.field == 1) { SourceClass.field++; }\n"
                + "        Random r = new Random(SourceClass.field);\n"
                + "        SourceClass.field = r.nextInt();\n"
                + "    }\n"
                + "\n"
                + "}\n"));
    }

    public void testMoveImports() throws Exception {
        writeFilesAndWaitForScan(src,
                new File("t/SourceClass.java", "package t;\n"
                + "import java.util.Random;\n"
                + "public class SourceClass {\n"
                + "    static int field;\n"
                + "\n"
                + "    public void movedMethod() {\n"
                + "        if(field==1) field++;\n"
                + "        Random r = new Random(field);\n"
                + "        field = r.nextInt();\n"
                + "    }\n"
                + "\n"
                + "    public void usage() {\n"
                + "        TargetClass tClass = new TargetClass();\n"
                + "        movedMethod();\n"
                + "    }\n"
                + "}\n"),
                new File("t/TargetClass.java", "package t;\n"
                + "public class TargetClass {\n"
                + "}\n"));
        performMove(src.getFileObject("t/SourceClass.java"), new int[]{2}, src.getFileObject("t/TargetClass.java"), Visibility.PUBLIC, false);
        verifyContent(src,
                new File("t/SourceClass.java", "package t;\n"
                + "import java.util.Random;\n"
                + "public class SourceClass {\n"
                + "    static int field;\n"
                + "\n"
                + "    public void usage() {\n"
                + "        TargetClass tClass = new TargetClass();\n"
                + "        tClass.movedMethod();\n"
                + "    }\n"
                + "}\n"),
                new File("t/TargetClass.java", "package t;\n"
                + "import java.util.Random;\n"
                + "public class TargetClass {\n"
                + "    public void movedMethod() {\n"
                + "        if (SourceClass.field == 1) { SourceClass.field++; }\n"
                + "        Random r = new Random(SourceClass.field);\n"
                + "        SourceClass.field = r.nextInt();\n"
                + "    }\n"
                + "\n"
                + "}\n"));
    }
    
    public void testMoveImportsb() throws Exception {
        writeFilesAndWaitForScan(src,
                new File("t/SourceClass.java", "package t;\n"
                + "import java.util.Random;\n"
                + "public class SourceClass {\n"
                + "\n"
                + "    public Random movedMethod() {\n"
                + "        return null;\n"
                + "    }\n"
                + "\n"
                + "    public void usage() {\n"
                + "        TargetClass tClass = new TargetClass();\n"
                + "        Random r = movedMethod();\n"
                + "    }\n"
                + "}\n"),
                new File("t/TargetClass.java", "package t;\n"
                + "public class TargetClass {\n"
                + "}\n"));
        performMove(src.getFileObject("t/SourceClass.java"), new int[]{1}, src.getFileObject("t/TargetClass.java"), Visibility.PUBLIC, false);
        verifyContent(src,
                new File("t/SourceClass.java", "package t;\n"
                + "import java.util.Random;\n"
                + "public class SourceClass {\n"
                + "\n"
                + "    public void usage() {\n"
                + "        TargetClass tClass = new TargetClass();\n"
                + "        Random r = tClass.movedMethod();\n"
                + "    }\n"
                + "}\n"),
                new File("t/TargetClass.java", "package t;\n"
                + "import java.util.Random;\n"
                + "public class TargetClass {\n"
                + "    public Random movedMethod() {\n"
                + "        return null;\n"
                + "    }\n"
                + "\n"
                + "}\n"));
    }

    public void testMoveParameterNotNeeded() throws Exception {
        writeFilesAndWaitForScan(src,
                new File("t/SourceClass.java", "package t;\n"
                + "public class SourceClass {\n"
                + "    static int field;\n"
                + "\n"
                + "    public void movedMethod() {\n"
                + "        if(field==1) field++;\n"
                + "    }\n"
                + "\n"
                + "    public void usage() {\n"
                + "        TargetClass tClass = new TargetClass();\n"
                + "        movedMethod();\n"
                + "    }\n"
                + "}\n"),
                new File("t/TargetClass.java", "package t;\n"
                + "public class TargetClass {\n"
                + "}\n"));
        performMove(src.getFileObject("t/SourceClass.java"), new int[]{2}, src.getFileObject("t/TargetClass.java"), Visibility.PUBLIC, false);
        verifyContent(src,
                new File("t/SourceClass.java", "package t;\n"
                + "public class SourceClass {\n"
                + "    static int field;\n"
                + "\n"
                + "    public void usage() {\n"
                + "        TargetClass tClass = new TargetClass();\n"
                + "        tClass.movedMethod();\n"
                + "    }\n"
                + "}\n"),
                new File("t/TargetClass.java", "package t;\n"
                + "public class TargetClass {\n"
                + "    public void movedMethod() {\n"
                + "        if (SourceClass.field == 1) { SourceClass.field++; }\n"
                + "    }\n"
                + "\n"
                + "}\n"));
    }

    public void testMoveParameterMissing() throws Exception {
        writeFilesAndWaitForScan(src,
                new File("t/SourceClass.java", "package t;\n"
                + "public class SourceClass {\n"
                + "    int field;\n"
                + "\n"
                + "    public void movedMethod() {\n"
                + "        if(field==1) field++;\n"
                + "    }\n"
                + "\n"
                + "    public void usage() {\n"
                + "        TargetClass tClass = new TargetClass();\n"
                + "        movedMethod();\n"
                + "    }\n"
                + "}\n"),
                new File("t/TargetClass.java", "package t;\n"
                + "public class TargetClass {\n"
                + "}\n"));
        performMove(src.getFileObject("t/SourceClass.java"), new int[]{2}, src.getFileObject("t/TargetClass.java"), Visibility.PUBLIC, false);
        verifyContent(src,
                new File("t/SourceClass.java", "package t;\n"
                + "public class SourceClass {\n"
                + "    int field;\n"
                + "\n"
                + "    public void usage() {\n"
                + "        TargetClass tClass = new TargetClass();\n"
                + "        tClass.movedMethod(this);\n"
                + "    }\n"
                + "}\n"),
                new File("t/TargetClass.java", "package t;\n"
                + "public class TargetClass {\n"
                + "    public void movedMethod(SourceClass sourceClass) {\n"
                + "        if (sourceClass.field == 1) { sourceClass.field++; }\n"
                + "    }\n"
                + "\n"
                + "}\n"));
    }

    public void testMoveExists() throws Exception {
        writeFilesAndWaitForScan(src,
                new File("t/A.java", "package t;\n"
                + "public class A {\n"
                + "    /** Something about i */\n"
                + "    static int i() { return 1; }\n"
                + "    public void foo() {\n"
                + "        System.out.println(i());\n"
                + "    }\n"
                + "}\n"),
                new File("t/B.java", "package t;\n"
                + "public class B {\n"
                + "    /** Something about j */\n"
                + "    static int i() { return 1; }\n"
                + "    public void foo() {\n"
                + "        System.out.println(i());\n"
                + "    }\n"
                + "}\n"));
        performMove(src.getFileObject("t/A.java"), new int[]{1}, src.getFileObject("t/B.java"), Visibility.PUBLIC, false, new Problem(true, "ERR_existingMethod"));
    }

    public void testMoveToLibrary() throws Exception {
        writeFilesAndWaitForScan(src,
                new File("t/A.java", "package t;\n"
                + "public class A {\n"
                + "    /** Something about i */\n"
                + "    static int i() { return 1; }\n"
                + "    public void foo() {\n"
                + "        System.out.println(i());\n"
                + "    }\n"
                + "}\n"));
        performMove(src.getFileObject("t/A.java"), new int[]{1}, "java.lang.String", Visibility.PUBLIC, new Problem(true, "ERR_MoveToLibrary"));
    }

//    TODO: Fix
//    public void testMoveFromLibrary() throws Exception {
//        writeFilesAndWaitForScan(src,
//                new File("t/A.java", "package t;\n"
//                + "public class A {\n"
//                + "    /** Something about i */\n"
//                + "    static int i() { return 1; }\n"
//                + "    public void foo() {\n"
//                + "        System.out.println(i());\n"
//                + "    }\n"
//                + "}\n"));
//        performMove("java.lang.String", new int[]{1}, src.getFileObject("t/A.java"), Visibility.PUBLIC, new Problem(true, "ERR_MoveFromLibrary"));
//    }
    public void testMoveSubSuper() throws Exception {
        writeFilesAndWaitForScan(src,
                new File("t/A.java", "package t;\n"
                + "public class A {\n"
                + "    /** Something about i */\n"
                + "    static int i() { return 1; }\n"
                + "    public void foo() {\n"
                + "        System.out.println(i());\n"
                + "    }\n"
                + "}\n"),
                new File("t/B.java", "package t;\n"
                + "public class B extends A {\n"
                + "    /** Something about j */\n"
                + "    static int j() { return 1; }\n"
                + "    public void foo() {\n"
                + "        System.out.println(j());\n"
                + "    }\n"
                + "}\n"));
        performMove(src.getFileObject("t/A.java"), new int[]{1}, src.getFileObject("t/A.java"), Visibility.PUBLIC, false, new Problem(true, "ERR_MoveToSameClass"));
        performMove(src.getFileObject("t/A.java"), new int[]{1}, src.getFileObject("t/B.java"), Visibility.PUBLIC, false, new Problem(true, "ERR_MoveToSubClass"));
        performMove(src.getFileObject("t/B.java"), new int[]{1}, src.getFileObject("t/A.java"), Visibility.PUBLIC, false, new Problem(true, "ERR_MoveToSuperClass"));
    }

    public void testMoveToStatic() throws Exception {
        writeFilesAndWaitForScan(src,
                new File("t/A.java", "package t;\n"
                + "public class A {\n"
                + "    /** Something about i */\n"
                + "    int i() { return 1; }\n"
                + "    public void foo() {\n"
                + "        B b = new B();\n"
                + "        System.out.println(i());\n"
                + "    }\n"
                + "}\n"),
                new File("t/B.java", "package t;\n"
                + "public class B {\n"
                + "    public static void main(String[] args) {\n"
                + "        A a = new A();\n"
                + "        System.out.println(a.i());\n"
                + "    }\n"
                + "}\n"),
                new File("t/C.java", "package t;\n"
                + "public class C {\n"
                + "    public void foo() {\n"
                + "        A a = new A();\n"
                + "        B b = new B();\n"
                + "        System.out.println(a.i());\n"
                + "    }\n"
                + "}\n"));
        performMove(src.getFileObject("t/A.java"), new int[]{1}, src.getFileObject("t/B.java"), Visibility.PUBLIC, false, new Problem(false, "WRN_NoAccessor"));
        verifyContent(src,
                new File("t/A.java", "package t;\n"
                + "public class A {\n"
                + "    public void foo() {\n"
                + "        B b = new B();\n"
                + "        System.out.println(b.i());\n"
                + "    }\n"
                + "}\n"),
                new File("t/B.java", "package t;\n"
                + "public class B {\n"
                + "    public static void main(String[] args) {\n"
                + "        A a = new A();\n"
                + "        System.out.println(a.i());\n"
                + "    }\n"
                + "    /** Something about i */\n"
                + "    public int i() { return 1; }\n"
                + "}\n"),
                new File("t/C.java", "package t;\n"
                + "public class C {\n"
                + "    public void foo() {\n"
                + "        A a = new A();\n"
                + "        B b = new B();\n"
                + "        System.out.println(b.i());\n"
                + "    }\n"
                + "}\n"));
    }

    public void testMoveStatic() throws Exception {
        writeFilesAndWaitForScan(src,
                new File("t/A.java", "package t;\n"
                + "public class A {\n"
                + "    /** Something about i */\n"
                + "    static int i(B b) { return b.i; }\n"
                + "    public void foo() {\n"
                + "        System.out.println(i(new B()));\n"
                + "    }\n"
                + "}\n"),
                new File("t/B.java", "package t;\n"
                + "public class B {\n"
                + "    public int i = 42;\n"
                + "    public void foo() {\n"
                + "        System.out.println(A.i(this));\n"
                + "    }\n"
                + "}\n"),
                new File("t/C.java", "package t;\n"
                + "public class C {\n"
                + "    public void foo() {\n"
                + "        System.out.println(A.i(new B()));\n"
                + "    }\n"
                + "}\n"));
        performMove(src.getFileObject("t/A.java"), new int[]{1}, src.getFileObject("t/B.java"), Visibility.PUBLIC, false);
        verifyContent(src,
                new File("t/A.java", "package t;\n"
                + "public class A {\n"
                + "    public void foo() {\n"
                + "        System.out.println(B.i(new B()));\n"
                + "    }\n"
                + "}\n"),
                new File("t/B.java", "package t;\n"
                + "public class B {\n"
                + "    /** Something about i */\n"
                + "    public static int i(B b) { return b.i; }\n"
                + "    public int i = 42;\n"
                + "    public void foo() {\n"
                + "        System.out.println(i(this));\n"
                + "    }\n"
                + "}\n"),
                new File("t/C.java", "package t;\n"
                + "public class C {\n"
                + "    public void foo() {\n"
                + "        System.out.println(B.i(new B()));\n"
                + "    }\n"
                + "}\n"));
    }
    
    public void test216700() throws Exception {
        writeFilesAndWaitForScan(src,
                new File("t/A.java", "package t;\n"
                + "public class A {\n"
                + "    public static void method() {\n"
                + "        A.method();\n"
                + "    }\n"
                + "}\n"),
                new File("t/B.java", "package t;\n"
                + "public class B {\n"
                + "}\n"),
                new File("t/C.java", "package t;\n"
                + "public class C {\n"
                + "    public void foo() {\n"
                + "        A.method();\n"
                + "    }\n"
                + "}\n"));
        performMove(src.getFileObject("t/A.java"), new int[]{1}, src.getFileObject("t/B.java"), Visibility.PUBLIC, false);
        verifyContent(src,
                new File("t/A.java", "package t;\n"
                + "public class A {\n"
                + "}\n"),
                new File("t/B.java", "package t;\n"
                + "public class B {\n"
                + "    public static void method() {\n"
                + "        B.method();\n"
                + "    }\n"
                + "}\n"),
                new File("t/C.java", "package t;\n"
                + "public class C {\n"
                + "    public void foo() {\n"
                + "        B.method();\n"
                + "    }\n"
                + "}\n"));
    }

    public void testMoveNoAccessor() throws Exception {
        writeFilesAndWaitForScan(src,
                new File("t/A.java", "package t;\n"
                + "public class A {\n"
                + "    /** Something about i */\n"
                + "    int i() { return 1; }\n"
                + "    public void foo() {\n"
                + "        System.out.println(i());\n"
                + "    }\n"
                + "}\n"),
                new File("t/B.java", "package t;\n"
                + "public class B {\n"
                + "    public void foo() {\n"
                + "        A a = new A();\n"
                + "        System.out.println(a.i());\n"
                + "    }\n"
                + "}\n"),
                new File("t/C.java", "package t;\n"
                + "public class C {\n"
                + "    public void foo() {\n"
                + "        A a = new A();\n"
                + "        B b = new B();\n"
                + "        System.out.println(a.i());\n"
                + "    }\n"
                + "}\n"));
        performMove(src.getFileObject("t/A.java"), new int[]{1}, src.getFileObject("t/B.java"), Visibility.PUBLIC, false, new Problem(false, "WRN_NoAccessor"));
        verifyContent(src,
                new File("t/A.java", "package t;\n"
                + "public class A {\n"
                + "    public void foo() {\n"
                + "        System.out.println(i());\n"
                + "    }\n"
                + "}\n"),
                new File("t/B.java", "package t;\n"
                + "public class B {\n"
                + "    public void foo() {\n"
                + "        A a = new A();\n"
                + "        System.out.println(i());\n"
                + "    }\n"
                + "    /** Something about i */\n"
                + "    public int i() { return 1; }\n"
                + "}\n"),
                new File("t/C.java", "package t;\n"
                + "public class C {\n"
                + "    public void foo() {\n"
                + "        A a = new A();\n"
                + "        B b = new B();\n"
                + "        System.out.println(b.i());\n"
                + "    }\n"
                + "}\n"));
    }

    public void testMoveGeneric() throws Exception {
        writeFilesAndWaitForScan(src,
                new File("t/A.java", "package t;\n"
                + "public class A <E> {\n"
                + "    /** Something about i */\n"
                + "    E i() { return null; }\n"
                + "    public void foo() {\n"
                + "        B b = new B();\n"
                + "        System.out.println(i());\n"
                + "    }\n"
                + "}\n"),
                new File("t/B.java", "package t;\n"
                + "public class B {\n"
                + "    public void foo() {\n"
                + "        A<String> a = new A<String>();\n"
                + "        System.out.println(a.i());\n"
                + "    }\n"
                + "}\n"));
        performMove(src.getFileObject("t/A.java"), new int[]{1}, src.getFileObject("t/B.java"), Visibility.PUBLIC, false);
        verifyContent(src,
                new File("t/A.java", "package t;\n"
                + "public class A <E> {\n"
                + "    public void foo() {\n"
                + "        B b = new B();\n"
                + "        System.out.println(b.<E>i());\n"
                + "    }\n"
                + "}\n"),
                new File("t/B.java", "package t;\n"
                + "public class B {\n"
                + "    public void foo() {\n"
                + "        A<String> a = new A<String>();\n"
                + "        System.out.println(this.<String>i());\n"
                + "    }\n"
                + "    /** Something about i */\n"
                + "    public <E> E i() { return null; }\n"
                + "}\n"));
    }

    public void testMoveInstance() throws Exception {
        writeFilesAndWaitForScan(src,
                new File("t/A.java", "package t;\n"
                + "public class A {\n"
                + "    /** Something about i */\n"
                + "    int i() { return 1; }\n"
                + "    public void foo() {\n"
                + "        B b = new B();\n"
                + "        System.out.println(i());\n"
                + "    }\n"
                + "}\n"),
                new File("t/B.java", "package t;\n"
                + "public class B {\n"
                + "    public void foo() {\n"
                + "        A a = new A();\n"
                + "        System.out.println(a.i());\n"
                + "    }\n"
                + "}\n"),
                new File("t/C.java", "package t;\n"
                + "public class C {\n"
                + "    public void foo() {\n"
                + "        A a = new A();\n"
                + "        B b = new B();\n"
                + "        System.out.println(a.i());\n"
                + "    }\n"
                + "}\n"));
        performMove(src.getFileObject("t/A.java"), new int[]{1}, src.getFileObject("t/B.java"), Visibility.PUBLIC, false);
        verifyContent(src,
                new File("t/A.java", "package t;\n"
                + "public class A {\n"
                + "    public void foo() {\n"
                + "        B b = new B();\n"
                + "        System.out.println(b.i());\n"
                + "    }\n"
                + "}\n"),
                new File("t/B.java", "package t;\n"
                + "public class B {\n"
                + "    public void foo() {\n"
                + "        A a = new A();\n"
                + "        System.out.println(i());\n"
                + "    }\n"
                + "    /** Something about i */\n"
                + "    public int i() { return 1; }\n"
                + "}\n"),
                new File("t/C.java", "package t;\n"
                + "public class C {\n"
                + "    public void foo() {\n"
                + "        A a = new A();\n"
                + "        B b = new B();\n"
                + "        System.out.println(b.i());\n"
                + "    }\n"
                + "}\n"));
    }

    public void testMoveDelegate() throws Exception {
        writeFilesAndWaitForScan(src,
                new File("t/A.java", "package t;\n"
                + "public class A {\n"
                + "    /** Something about i */\n"
                + "    int i(B b) { return b.b; }\n"
                + "    public void foo() {\n"
                + "        B b = new B();\n"
                + "        System.out.println(i(new B()));\n"
                + "    }\n"
                + "}\n"),
                new File("t/B.java", "package t;\n"
                + "public class B {\n"
                + "    public int b = 5;\n"
                + "    public void foo() {\n"
                + "        A a = new A();\n"
                + "        System.out.println(a.i(this));\n"
                + "    }\n"
                + "}\n"),
                new File("t/C.java", "package t;\n"
                + "public class C {\n"
                + "    public void foo() {\n"
                + "        A a = new A();\n"
                + "        B b = new B();\n"
                + "        System.out.println(a.i(b));\n"
                + "    }\n"
                + "}\n"));

        performMove(src.getFileObject("t/A.java"), new int[]{1}, src.getFileObject("t/B.java"), Visibility.PUBLIC, true);
        verifyContent(src,
                new File("t/A.java", "package t;\n"
                + "public class A {\n"
                + "    /** Something about i */\n"
                + "    int i(B b) { return b.i(); }\n"
                + "    public void foo() {\n"
                + "        B b = new B();\n"
                + "        System.out.println(i(new B()));\n"
                + "    }\n"
                + "}\n"),
                new File("t/B.java", "package t;\n"
                + "public class B {\n"
                + "    public int b = 5;\n"
                + "    public void foo() {\n"
                + "        A a = new A();\n"
                + "        System.out.println(a.i(this));\n"
                + "    }\n"
                + "    /** Something about i */\n"
                + "    public int i() { return this.b; }\n"
                + "}\n"),
                new File("t/C.java", "package t;\n"
                + "public class C {\n"
                + "    public void foo() {\n"
                + "        A a = new A();\n"
                + "        B b = new B();\n"
                + "        System.out.println(a.i(b));\n"
                + "    }\n"
                + "}\n"));
    }

    public void testMoveInstanceParameter() throws Exception {
        writeFilesAndWaitForScan(src,
                new File("t/A.java", "package t;\n"
                + "public class A {\n"
                + "    /** Something about i */\n"
                + "    int i(B b) { return b.b; }\n"
                + "    public void foo() {\n"
                + "        B b = new B();\n"
                + "        System.out.println(i(new B()));\n"
                + "    }\n"
                + "}\n"),
                new File("t/B.java", "package t;\n"
                + "public class B {\n"
                + "    public int b = 5;\n"
                + "    public void foo() {\n"
                + "        A a = new A();\n"
                + "        System.out.println(a.i(this));\n"
                + "    }\n"
                + "}\n"),
                new File("t/C.java", "package t;\n"
                + "public class C {\n"
                + "    public void foo() {\n"
                + "        A a = new A();\n"
                + "        B b = new B();\n"
                + "        System.out.println(a.i(b));\n"
                + "    }\n"
                + "}\n"));
        performMove(src.getFileObject("t/A.java"), new int[]{1}, src.getFileObject("t/B.java"), Visibility.PUBLIC, false);
        verifyContent(src,
                new File("t/A.java", "package t;\n"
                + "public class A {\n"
                + "    public void foo() {\n"
                + "        B b = new B();\n"
                + "        System.out.println(new B().i());\n"
                + "    }\n"
                + "}\n"),
                new File("t/B.java", "package t;\n"
                + "public class B {\n"
                + "    public int b = 5;\n"
                + "    public void foo() {\n"
                + "        A a = new A();\n"
                + "        System.out.println(i());\n"
                + "    }\n"
                + "    /** Something about i */\n"
                + "    public int i() { return this.b; }\n"
                + "}\n"),
                new File("t/C.java", "package t;\n"
                + "public class C {\n"
                + "    public void foo() {\n"
                + "        A a = new A();\n"
                + "        B b = new B();\n"
                + "        System.out.println(b.i());\n"
                + "    }\n"
                + "}\n"));
    }

    public void testMoveInstanceLocalAccessors() throws Exception {
        writeFilesAndWaitForScan(src,
                new File("t/A.java", "package t;\n"
                + "public class A {\n"
                + "    /** Something about i */\n"
                + "    int i(B b) { return b.b; }\n"
                + "    public void foo() {\n"
                + "        B b = new B();\n"
                + "        System.out.println(i(new B()));\n"
                + "    }\n"
                + "}\n"),
                new File("t/B.java", "package t;\n"
                + "public class B {\n"
                + "    public int b = 5;\n"
                + "    public void foo() {\n"
                + "        A a = new A();\n"
                + "        System.out.println(a.i(this));\n"
                + "    }\n"
                + "}\n"),
                new File("t/C.java", "package t;\n"
                + "public class C {\n"
                + "    public void foo() {\n"
                + "        A a = new A();\n"
                + "        B b = new B();\n"
                + "        System.out.println(a.i(b));\n"
                + "    }\n"
                + "}\n"));
        performMove(src.getFileObject("t/A.java"), new int[]{1}, src.getFileObject("t/B.java"), Visibility.PUBLIC, false);
        verifyContent(src,
                new File("t/A.java", "package t;\n"
                + "public class A {\n"
                + "    public void foo() {\n"
                + "        B b = new B();\n"
                + "        System.out.println(new B().i());\n"
                + "    }\n"
                + "}\n"),
                new File("t/B.java", "package t;\n"
                + "public class B {\n"
                + "    public int b = 5;\n"
                + "    public void foo() {\n"
                + "        A a = new A();\n"
                + "        System.out.println(i());\n"
                + "    }\n"
                + "    /** Something about i */\n"
                + "    public int i() { return this.b; }\n"
                + "}\n"),
                new File("t/C.java", "package t;\n"
                + "public class C {\n"
                + "    public void foo() {\n"
                + "        A a = new A();\n"
                + "        B b = new B();\n"
                + "        System.out.println(b.i());\n"
                + "    }\n"
                + "}\n"));
    }

    public void testVideoStore() throws Exception {
        writeFilesAndWaitForScan(src,
                new File("videostore/Movie.java", "package videostore;\n"
                + "\n"
                + "public class Movie {\n"
                + "    \n"
                + "    public static final int CHILDRENS = 2;\n"
                + "    public static final int REGULAR = 0;\n"
                + "    public static final int NEW_RELEASE = 1;\n"
                + "\n"
                + "    private String title;\n"
                + "    private int priceCode;\n"
                + "\n"
                + "    public Movie(String title, int priceCode) {\n"
                + "        this.title = title;\n"
                + "        this.priceCode = priceCode;\n"
                + "    }\n"
                + "\n"
                + "    public int getPriceCode() {\n"
                + "        return priceCode;\n"
                + "    }\n"
                + "\n"
                + "    public void setPriceCode(int priceCode) {\n"
                + "        this.priceCode = priceCode;\n"
                + "    }\n"
                + "\n"
                + "    public String getTitle() {\n"
                + "        return title;\n"
                + "    }\n"
                + "}"),
                new File("videostore/Rental.java", "package videostore;\n"
                + "\n"
                + "public class Rental {\n"
                + "\n"
                + "    private Movie movie;\n"
                + "    private int daysRent;\n"
                + "\n"
                + "    public Rental(Movie movie, int daysRent) {\n"
                + "        this.movie = movie;\n"
                + "        this.daysRent = daysRent;\n"
                + "    }\n"
                + "\n"
                + "    public Movie getMovie() {\n"
                + "        return movie;\n"
                + "    }\n"
                + "\n"
                + "    public int getDaysRent() {\n"
                + "        return daysRent;\n"
                + "    }\n"
                + "}"),
                new File("videostore/Customer.java", "package videostore;\n"
                + "\n"
                + "import java.util.Enumeration;\n"
                + "import java.util.Vector;\n"
                + "\n"
                + "public class Customer {\n"
                + "\n"
                + "    private String name;\n"
                + "    private Vector rentals = new Vector();\n"
                + "\n"
                + "    public Customer(String name) {\n"
                + "        this.name = name;\n"
                + "    }\n"
                + "    \n"
                + "    public void addRental(Rental rental) {\n"
                + "        rentals.addElement(rental);\n"
                + "    }\n"
                + "\n"
                + "    public String getName() {\n"
                + "        return name;\n"
                + "    }\n"
                + "    \n"
                + "    public String statement() {\n"
                + "        double totalAmount = 0;\n"
                + "        int frequentRenterpoints = 0;\n"
                + "        Enumeration rentalelements = rentals.elements();\n"
                + "        String result = \"Rental Record for \" + getName() + \"\\n\";\n"
                + "        while(rentalelements.hasMoreElements()) {\n"
                + "            Rental each = (Rental) rentalelements.nextElement();\n"
                + "            double thisAmount = amountFor(each);\n"
                + "            \n"
                + "            // add frequent renter points\n"
                + "            frequentRenterpoints++;\n"
                + "            // add bonus for a two day new release rental\n"
                + "            if((each.getMovie().getPriceCode() == Movie.NEW_RELEASE) &&\n"
                + "                    each.getDaysRent() > 1) frequentRenterpoints++;\n"
                + "            \n"
                + "            // show figures for this rental\n"
                + "            result += \"\\t\" + each.getMovie().getTitle() + \"\\t\" +\n"
                + "                    String.valueOf(thisAmount) + \"\\n\";\n"
                + "            totalAmount += thisAmount;\n"
                + "        }\n"
                + "        // add footer lines\n"
                + "        result += \"Amount owed is \" + String.valueOf(totalAmount) + \"\\n\";\n"
                + "        result += \"You earned \" + String.valueOf(frequentRenterpoints) +\n"
                + "                \" frequent renter points\";\n"
                + "        return result;\n"
                + "    }\n"
                + "\n"
                + "    private double amountFor(Rental rental) {\n"
                + "        // determine amounts for each line\n"
                + "        double result = 0;\n"
                + "        switch(rental.getMovie().getPriceCode()) {\n"
                + "            case Movie.REGULAR:\n"
                + "                result += 2;\n"
                + "                if(rental.getDaysRent() > 2)\n"
                + "                    result += (rental.getDaysRent() - 2) * 1.5;\n"
                + "                break;\n"
                + "            case Movie.NEW_RELEASE:\n"
                + "                result += rental.getDaysRent() * 3;\n"
                + "                break;\n"
                + "            case Movie.CHILDRENS:\n"
                + "                result += 1.5;\n"
                + "                if(rental.getDaysRent() > 3)\n"
                + "                    result += (rental.getDaysRent() -3) * 1.5;\n"
                + "                break;\n"
                + "        }\n"
                + "        return result;\n"
                + "    }\n"
                + "}"));
        performMove(src.getFileObject("videostore/Customer.java"), new int[]{6}, src.getFileObject("videostore/Rental.java"), Visibility.ESCALATE, false);
        verifyContent(src,
                new File("videostore/Movie.java", "package videostore;\n"
                + "\n"
                + "public class Movie {\n"
                + "    \n"
                + "    public static final int CHILDRENS = 2;\n"
                + "    public static final int REGULAR = 0;\n"
                + "    public static final int NEW_RELEASE = 1;\n"
                + "\n"
                + "    private String title;\n"
                + "    private int priceCode;\n"
                + "\n"
                + "    public Movie(String title, int priceCode) {\n"
                + "        this.title = title;\n"
                + "        this.priceCode = priceCode;\n"
                + "    }\n"
                + "\n"
                + "    public int getPriceCode() {\n"
                + "        return priceCode;\n"
                + "    }\n"
                + "\n"
                + "    public void setPriceCode(int priceCode) {\n"
                + "        this.priceCode = priceCode;\n"
                + "    }\n"
                + "\n"
                + "    public String getTitle() {\n"
                + "        return title;\n"
                + "    }\n"
                + "}"),
                new File("videostore/Rental.java", "package videostore;\n"
                + "\n"
                + "public class Rental {\n"
                + "\n"
                + "    private Movie movie;\n"
                + "    private int daysRent;\n"
                + "\n"
                + "    public Rental(Movie movie, int daysRent) {\n"
                + "        this.movie = movie;\n"
                + "        this.daysRent = daysRent;\n"
                + "    }\n"
                + "\n"
                + "    public Movie getMovie() {\n"
                + "        return movie;\n"
                + "    }\n"
                + "\n"
                + "    public int getDaysRent() {\n"
                + "        return daysRent;\n"
                + "    }\n"
                + "\n"
                + "    double amountFor() {\n"
                + "        // determine amounts for each line\n"
                + "        double result = 0;\n"
                + "        switch (this.getMovie().getPriceCode()) {\n"
                + "            case Movie.REGULAR:\n"
                + "                result += 2;\n"
                + "                if (this.getDaysRent() > 2) {\n"
                + "                    result += (this.getDaysRent() - 2) * 1.5;\n"
                + "                }\n"
                + "                break;\n"
                + "            case Movie.NEW_RELEASE:\n"
                + "                result += this.getDaysRent() * 3;\n"
                + "                break;\n"
                + "            case Movie.CHILDRENS:\n"
                + "                result += 1.5;\n"
                + "                if (this.getDaysRent() > 3) {\n"
                + "                    result += (this.getDaysRent() - 3) * 1.5;\n"
                + "                }\n"
                + "                break;\n"
                + "        }\n"
                + "        return result;\n"
                + "    }\n"
                + "}"),
                new File("videostore/Customer.java", "package videostore;\n"
                + "\n"
                + "import java.util.Enumeration;\n"
                + "import java.util.Vector;\n"
                + "\n"
                + "public class Customer {\n"
                + "\n"
                + "    private String name;\n"
                + "    private Vector rentals = new Vector();\n"
                + "\n"
                + "    public Customer(String name) {\n"
                + "        this.name = name;\n"
                + "    }\n"
                + "    \n"
                + "    public void addRental(Rental rental) {\n"
                + "        rentals.addElement(rental);\n"
                + "    }\n"
                + "\n"
                + "    public String getName() {\n"
                + "        return name;\n"
                + "    }\n"
                + "    \n"
                + "    public String statement() {\n"
                + "        double totalAmount = 0;\n"
                + "        int frequentRenterpoints = 0;\n"
                + "        Enumeration rentalelements = rentals.elements();\n"
                + "        String result = \"Rental Record for \" + getName() + \"\\n\";\n"
                + "        while(rentalelements.hasMoreElements()) {\n"
                + "            Rental each = (Rental) rentalelements.nextElement();\n"
                + "            double thisAmount = each.amountFor();\n"
                + "            \n"
                + "            // add frequent renter points\n"
                + "            frequentRenterpoints++;\n"
                + "            // add bonus for a two day new release rental\n"
                + "            if((each.getMovie().getPriceCode() == Movie.NEW_RELEASE) &&\n"
                + "                    each.getDaysRent() > 1) frequentRenterpoints++;\n"
                + "            \n"
                + "            // show figures for this rental\n"
                + "            result += \"\\t\" + each.getMovie().getTitle() + \"\\t\" +\n"
                + "                    String.valueOf(thisAmount) + \"\\n\";\n"
                + "            totalAmount += thisAmount;\n"
                + "        }\n"
                + "        // add footer lines\n"
                + "        result += \"Amount owed is \" + String.valueOf(totalAmount) + \"\\n\";\n"
                + "        result += \"You earned \" + String.valueOf(frequentRenterpoints) +\n"
                + "                \" frequent renter points\";\n"
                + "        return result;\n"
                + "    }\n"
                + "\n"
                + "}"));
    }

    public void testVideoStore2() throws Exception {
        writeFilesAndWaitForScan(src,
                new File("videostore/Movie.java", "package videostore;\n"
                + "\n"
                + "public class Movie {\n"
                + "    \n"
                + "    public static final int CHILDRENS = 2;\n"
                + "    public static final int REGULAR = 0;\n"
                + "    public static final int NEW_RELEASE = 1;\n"
                + "\n"
                + "    private String title;\n"
                + "    private int priceCode;\n"
                + "\n"
                + "    public Movie(String title, int priceCode) {\n"
                + "        this.title = title;\n"
                + "        this.priceCode = priceCode;\n"
                + "    }\n"
                + "\n"
                + "    public int getPriceCode() {\n"
                + "        return priceCode;\n"
                + "    }\n"
                + "\n"
                + "    public void setPriceCode(int priceCode) {\n"
                + "        this.priceCode = priceCode;\n"
                + "    }\n"
                + "\n"
                + "    public String getTitle() {\n"
                + "        return title;\n"
                + "    }\n"
                + "}"),
                new File("videostore/Rental.java", "package videostore;\n"
                + "\n"
                + "public class Rental {\n"
                + "\n"
                + "    private Movie movie;\n"
                + "    private int daysRent;\n"
                + "\n"
                + "    public Rental(Movie movie, int daysRent) {\n"
                + "        this.movie = movie;\n"
                + "        this.daysRent = daysRent;\n"
                + "    }\n"
                + "\n"
                + "    public Movie getMovie() {\n"
                + "        return movie;\n"
                + "    }\n"
                + "\n"
                + "    public int getDaysRent() {\n"
                + "        return daysRent;\n"
                + "    }\n"
                + "\n"
                + "    double amountFor() {\n"
                + "        // determine amounts for each line\n"
                + "        double result = 0;\n"
                + "        switch (getMovie().getPriceCode()) {\n"
                + "            case Movie.REGULAR:\n"
                + "                result += 2;\n"
                + "                if (this.getDaysRent() > 2) {\n"
                + "                    result += (this.getDaysRent() - 2) * 1.5;\n"
                + "                }\n"
                + "                break;\n"
                + "            case Movie.NEW_RELEASE:\n"
                + "                result += getDaysRent() * 3;\n"
                + "                break;\n"
                + "            case Movie.CHILDRENS:\n"
                + "                result += 1.5;\n"
                + "                if (this.getDaysRent() > 3) {\n"
                + "                    result += (getDaysRent() - 3) * 1.5;\n"
                + "                }\n"
                + "                break;\n"
                + "        }\n"
                + "        return result;\n"
                + "    }\n"
                + "}"),
                new File("videostore/Customer.java", "package videostore;\n"
                + "\n"
                + "import java.util.Enumeration;\n"
                + "import java.util.Vector;\n"
                + "\n"
                + "public class Customer {\n"
                + "\n"
                + "    private String name;\n"
                + "    private Vector rentals = new Vector();\n"
                + "\n"
                + "    public Customer(String name) {\n"
                + "        this.name = name;\n"
                + "    }\n"
                + "    \n"
                + "    public void addRental(Rental rental) {\n"
                + "        rentals.addElement(rental);\n"
                + "    }\n"
                + "\n"
                + "    public String getName() {\n"
                + "        return name;\n"
                + "    }\n"
                + "    \n"
                + "    public String statement() {\n"
                + "        double totalAmount = 0;\n"
                + "        int frequentRenterpoints = 0;\n"
                + "        Enumeration rentalelements = rentals.elements();\n"
                + "        String result = \"Rental Record for \" + getName() + \"\\n\";\n"
                + "        while(rentalelements.hasMoreElements()) {\n"
                + "            Rental each = (Rental) rentalelements.nextElement();\n"
                + "            double thisAmount = each.amountFor();\n"
                + "            \n"
                + "            // add frequent renter points\n"
                + "            frequentRenterpoints++;\n"
                + "            // add bonus for a two day new release rental\n"
                + "            if((each.getMovie().getPriceCode() == Movie.NEW_RELEASE) &&\n"
                + "                    each.getDaysRent() > 1) frequentRenterpoints++;\n"
                + "            \n"
                + "            // show figures for this rental\n"
                + "            result += \"\\t\" + each.getMovie().getTitle() + \"\\t\" +\n"
                + "                    String.valueOf(thisAmount) + \"\\n\";\n"
                + "            totalAmount += thisAmount;\n"
                + "        }\n"
                + "        // add footer lines\n"
                + "        result += \"Amount owed is \" + String.valueOf(totalAmount) + \"\\n\";\n"
                + "        result += \"You earned \" + String.valueOf(frequentRenterpoints) +\n"
                + "                \" frequent renter points\";\n"
                + "        return result;\n"
                + "    }\n"
                + "\n"
                + "}"));
        performMove(src.getFileObject("videostore/Rental.java"), new int[]{5}, src.getFileObject("videostore/Customer.java"), Visibility.PRIVATE, false);
        verifyContent(src,
                new File("videostore/Movie.java", "package videostore;\n"
                + "\n"
                + "public class Movie {\n"
                + "    \n"
                + "    public static final int CHILDRENS = 2;\n"
                + "    public static final int REGULAR = 0;\n"
                + "    public static final int NEW_RELEASE = 1;\n"
                + "\n"
                + "    private String title;\n"
                + "    private int priceCode;\n"
                + "\n"
                + "    public Movie(String title, int priceCode) {\n"
                + "        this.title = title;\n"
                + "        this.priceCode = priceCode;\n"
                + "    }\n"
                + "\n"
                + "    public int getPriceCode() {\n"
                + "        return priceCode;\n"
                + "    }\n"
                + "\n"
                + "    public void setPriceCode(int priceCode) {\n"
                + "        this.priceCode = priceCode;\n"
                + "    }\n"
                + "\n"
                + "    public String getTitle() {\n"
                + "        return title;\n"
                + "    }\n"
                + "}"),
                new File("videostore/Rental.java", "package videostore;\n"
                + "\n"
                + "public class Rental {\n"
                + "\n"
                + "    private Movie movie;\n"
                + "    private int daysRent;\n"
                + "\n"
                + "    public Rental(Movie movie, int daysRent) {\n"
                + "        this.movie = movie;\n"
                + "        this.daysRent = daysRent;\n"
                + "    }\n"
                + "\n"
                + "    public Movie getMovie() {\n"
                + "        return movie;\n"
                + "    }\n"
                + "\n"
                + "    public int getDaysRent() {\n"
                + "        return daysRent;\n"
                + "    }\n"
                + "}"),
                new File("videostore/Customer.java", "package videostore;\n"
                + "\n"
                + "import java.util.Enumeration;\n"
                + "import java.util.Vector;\n"
                + "\n"
                + "public class Customer {\n"
                + "\n"
                + "    private String name;\n"
                + "    private Vector rentals = new Vector();\n"
                + "\n"
                + "    public Customer(String name) {\n"
                + "        this.name = name;\n"
                + "    }\n"
                + "    \n"
                + "    public void addRental(Rental rental) {\n"
                + "        rentals.addElement(rental);\n"
                + "    }\n"
                + "\n"
                + "    public String getName() {\n"
                + "        return name;\n"
                + "    }\n"
                + "    \n"
                + "    public String statement() {\n"
                + "        double totalAmount = 0;\n"
                + "        int frequentRenterpoints = 0;\n"
                + "        Enumeration rentalelements = rentals.elements();\n"
                + "        String result = \"Rental Record for \" + getName() + \"\\n\";\n"
                + "        while(rentalelements.hasMoreElements()) {\n"
                + "            Rental each = (Rental) rentalelements.nextElement();\n"
                + "            double thisAmount = amountFor(each);\n"
                + "            \n"
                + "            // add frequent renter points\n"
                + "            frequentRenterpoints++;\n"
                + "            // add bonus for a two day new release rental\n"
                + "            if((each.getMovie().getPriceCode() == Movie.NEW_RELEASE) &&\n"
                + "                    each.getDaysRent() > 1) frequentRenterpoints++;\n"
                + "            \n"
                + "            // show figures for this rental\n"
                + "            result += \"\\t\" + each.getMovie().getTitle() + \"\\t\" +\n"
                + "                    String.valueOf(thisAmount) + \"\\n\";\n"
                + "            totalAmount += thisAmount;\n"
                + "        }\n"
                + "        // add footer lines\n"
                + "        result += \"Amount owed is \" + String.valueOf(totalAmount) + \"\\n\";\n"
                + "        result += \"You earned \" + String.valueOf(frequentRenterpoints) +\n"
                + "                \" frequent renter points\";\n"
                + "        return result;\n"
                + "    }\n"
                + "\n"
                + "    private double amountFor(Rental rental) {\n"
                + "        // determine amounts for each line\n"
                + "        double result = 0;\n"
                + "        switch (rental.getMovie().getPriceCode()) {\n"
                + "            case Movie.REGULAR:\n"
                + "                result += 2;\n"
                + "                if (rental.getDaysRent() > 2) {\n"
                + "                    result += (rental.getDaysRent() - 2) * 1.5;\n"
                + "                }\n"
                + "                break;\n"
                + "            case Movie.NEW_RELEASE:\n"
                + "                result += rental.getDaysRent() * 3;\n"
                + "                break;\n"
                + "            case Movie.CHILDRENS:\n"
                + "                result += 1.5;\n"
                + "                if (rental.getDaysRent() > 3) {\n"
                + "                    result += (rental.getDaysRent() - 3) * 1.5;\n"
                + "                }\n"
                + "                break;\n"
                + "        }\n"
                + "        return result;\n"
                + "    }\n"
                + "}"));
    }

    public void testVideoStore3() throws Exception {
        writeFilesAndWaitForScan(src,
                new File("video/Movie.java", "package video;\n"
                + "\n"
                + "public class Movie {\n"
                + "    \n"
                + "    public static final int CHILDRENS = 2;\n"
                + "    public static final int REGULAR = 0;\n"
                + "    public static final int NEW_RELEASE = 1;\n"
                + "\n"
                + "    private String title;\n"
                + "    private int priceCode;\n"
                + "\n"
                + "    public Movie(String title, int priceCode) {\n"
                + "        this.title = title;\n"
                + "        this.priceCode = priceCode;\n"
                + "    }\n"
                + "\n"
                + "    public int getPriceCode() {\n"
                + "        return priceCode;\n"
                + "    }\n"
                + "\n"
                + "    public void setPriceCode(int priceCode) {\n"
                + "        this.priceCode = priceCode;\n"
                + "    }\n"
                + "\n"
                + "    public String getTitle() {\n"
                + "        return title;\n"
                + "    }\n"
                + "}"),
                new File("video/Rental.java", "package video;\n"
                + "\n"
                + "public class Rental {\n"
                + "\n"
                + "    private Movie movie;\n"
                + "    private int daysRent;\n"
                + "\n"
                + "    public Rental(Movie movie, int daysRent) {\n"
                + "        this.movie = movie;\n"
                + "        this.daysRent = daysRent;\n"
                + "    }\n"
                + "\n"
                + "    public Movie getMovie() {\n"
                + "        return movie;\n"
                + "    }\n"
                + "\n"
                + "    public int getDaysRent() {\n"
                + "        return daysRent;\n"
                + "    }\n"
                + "}"),
                new File("videostore/Customer.java", "package videostore;\n"
                + "\n"
                + "import video.Movie;\n"
                + "import video.Rental;\n"
                + "import java.util.Enumeration;\n"
                + "import java.util.Vector;\n"
                + "\n"
                + "public class Customer {\n"
                + "\n"
                + "    private String name;\n"
                + "    private Vector rentals = new Vector();\n"
                + "\n"
                + "    public Customer(String name) {\n"
                + "        this.name = name;\n"
                + "    }\n"
                + "    \n"
                + "    public void addRental(Rental rental) {\n"
                + "        rentals.addElement(rental);\n"
                + "    }\n"
                + "\n"
                + "    public String getName() {\n"
                + "        return name;\n"
                + "    }\n"
                + "    \n"
                + "    public String statement() {\n"
                + "        double totalAmount = 0;\n"
                + "        int frequentRenterpoints = 0;\n"
                + "        Enumeration rentalelements = rentals.elements();\n"
                + "        String result = \"Rental Record for \" + getName() + \"\\n\";\n"
                + "        while(rentalelements.hasMoreElements()) {\n"
                + "            Rental each = (Rental) rentalelements.nextElement();\n"
                + "            double thisAmount = amountFor(each);\n"
                + "            \n"
                + "            // add frequent renter points\n"
                + "            frequentRenterpoints++;\n"
                + "            // add bonus for a two day new release rental\n"
                + "            if((each.getMovie().getPriceCode() == Movie.NEW_RELEASE) &&\n"
                + "                    each.getDaysRent() > 1) frequentRenterpoints++;\n"
                + "            \n"
                + "            // show figures for this rental\n"
                + "            result += \"\\t\" + each.getMovie().getTitle() + \"\\t\" +\n"
                + "                    String.valueOf(thisAmount) + \"\\n\";\n"
                + "            totalAmount += thisAmount;\n"
                + "        }\n"
                + "        // add footer lines\n"
                + "        result += \"Amount owed is \" + String.valueOf(totalAmount) + \"\\n\";\n"
                + "        result += \"You earned \" + String.valueOf(frequentRenterpoints) +\n"
                + "                \" frequent renter points\";\n"
                + "        return result;\n"
                + "    }\n"
                + "\n"
                + "    private double amountFor(Rental rental) {\n"
                + "        // determine amounts for each line\n"
                + "        double result = 0;\n"
                + "        switch(rental.getMovie().getPriceCode()) {\n"
                + "            case Movie.REGULAR:\n"
                + "                result += 2;\n"
                + "                if(rental.getDaysRent() > 2)\n"
                + "                    result += (rental.getDaysRent() - 2) * 1.5;\n"
                + "                break;\n"
                + "            case Movie.NEW_RELEASE:\n"
                + "                result += rental.getDaysRent() * 3;\n"
                + "                break;\n"
                + "            case Movie.CHILDRENS:\n"
                + "                result += 1.5;\n"
                + "                if(rental.getDaysRent() > 3)\n"
                + "                    result += (rental.getDaysRent() -3) * 1.5;\n"
                + "                break;\n"
                + "        }\n"
                + "        return result;\n"
                + "    }\n"
                + "}"));
        performMove(src.getFileObject("videostore/Customer.java"), new int[]{6}, src.getFileObject("video/Rental.java"), Visibility.ESCALATE, false);
        verifyContent(src,
                new File("video/Movie.java", "package video;\n"
                + "\n"
                + "public class Movie {\n"
                + "    \n"
                + "    public static final int CHILDRENS = 2;\n"
                + "    public static final int REGULAR = 0;\n"
                + "    public static final int NEW_RELEASE = 1;\n"
                + "\n"
                + "    private String title;\n"
                + "    private int priceCode;\n"
                + "\n"
                + "    public Movie(String title, int priceCode) {\n"
                + "        this.title = title;\n"
                + "        this.priceCode = priceCode;\n"
                + "    }\n"
                + "\n"
                + "    public int getPriceCode() {\n"
                + "        return priceCode;\n"
                + "    }\n"
                + "\n"
                + "    public void setPriceCode(int priceCode) {\n"
                + "        this.priceCode = priceCode;\n"
                + "    }\n"
                + "\n"
                + "    public String getTitle() {\n"
                + "        return title;\n"
                + "    }\n"
                + "}"),
                new File("video/Rental.java", "package video;\n"
                + "\n"
                + "public class Rental {\n"
                + "\n"
                + "    private Movie movie;\n"
                + "    private int daysRent;\n"
                + "\n"
                + "    public Rental(Movie movie, int daysRent) {\n"
                + "        this.movie = movie;\n"
                + "        this.daysRent = daysRent;\n"
                + "    }\n"
                + "\n"
                + "    public Movie getMovie() {\n"
                + "        return movie;\n"
                + "    }\n"
                + "\n"
                + "    public int getDaysRent() {\n"
                + "        return daysRent;\n"
                + "    }\n"
                + "\n"
                + "    public double amountFor() {\n"
                + "        // determine amounts for each line\n"
                + "        double result = 0;\n"
                + "        switch (this.getMovie().getPriceCode()) {\n"
                + "            case Movie.REGULAR:\n"
                + "                result += 2;\n"
                + "                if (this.getDaysRent() > 2) {\n"
                + "                    result += (this.getDaysRent() - 2) * 1.5;\n"
                + "                }\n"
                + "                break;\n"
                + "            case Movie.NEW_RELEASE:\n"
                + "                result += this.getDaysRent() * 3;\n"
                + "                break;\n"
                + "            case Movie.CHILDRENS:\n"
                + "                result += 1.5;\n"
                + "                if (this.getDaysRent() > 3) {\n"
                + "                    result += (this.getDaysRent() - 3) * 1.5;\n"
                + "                }\n"
                + "                break;\n"
                + "        }\n"
                + "        return result;\n"
                + "    }\n"
                + "}"),
                new File("videostore/Customer.java", "package videostore;\n"
                + "\n"
                + "import video.Movie;\n"
                + "import video.Rental;\n"
                + "import java.util.Enumeration;\n"
                + "import java.util.Vector;\n"
                + "\n"
                + "public class Customer {\n"
                + "\n"
                + "    private String name;\n"
                + "    private Vector rentals = new Vector();\n"
                + "\n"
                + "    public Customer(String name) {\n"
                + "        this.name = name;\n"
                + "    }\n"
                + "    \n"
                + "    public void addRental(Rental rental) {\n"
                + "        rentals.addElement(rental);\n"
                + "    }\n"
                + "\n"
                + "    public String getName() {\n"
                + "        return name;\n"
                + "    }\n"
                + "    \n"
                + "    public String statement() {\n"
                + "        double totalAmount = 0;\n"
                + "        int frequentRenterpoints = 0;\n"
                + "        Enumeration rentalelements = rentals.elements();\n"
                + "        String result = \"Rental Record for \" + getName() + \"\\n\";\n"
                + "        while(rentalelements.hasMoreElements()) {\n"
                + "            Rental each = (Rental) rentalelements.nextElement();\n"
                + "            double thisAmount = each.amountFor();\n"
                + "            \n"
                + "            // add frequent renter points\n"
                + "            frequentRenterpoints++;\n"
                + "            // add bonus for a two day new release rental\n"
                + "            if((each.getMovie().getPriceCode() == Movie.NEW_RELEASE) &&\n"
                + "                    each.getDaysRent() > 1) frequentRenterpoints++;\n"
                + "            \n"
                + "            // show figures for this rental\n"
                + "            result += \"\\t\" + each.getMovie().getTitle() + \"\\t\" +\n"
                + "                    String.valueOf(thisAmount) + \"\\n\";\n"
                + "            totalAmount += thisAmount;\n"
                + "        }\n"
                + "        // add footer lines\n"
                + "        result += \"Amount owed is \" + String.valueOf(totalAmount) + \"\\n\";\n"
                + "        result += \"You earned \" + String.valueOf(frequentRenterpoints) +\n"
                + "                \" frequent renter points\";\n"
                + "        return result;\n"
                + "    }\n"
                + "\n"
                + "}"));
    }

    public void testMoveMethodRef1() throws Exception {
        writeFilesAndWaitForScan(src,
                new File("t/TargetClass.java", "package t;\n"
                + "import java.util.function.BooleanSupplier;\n"
                + "public class TargetClass {\n"
                + "    public static void doStuff(BooleanSupplier source) {\n"
                + "        boolean val = source.getAsBoolean();\n"
                + "    }\n"
                + "    public static void prepareStuff() {\n"
                + "       doStuff(SourceClass::moveThis);\n"
                + "    }\n"
                + "}\n"),
                new File("t/SourceClass.java", "package t;\n"
                + "public class SourceClass {\n"
                + "   public static boolean moveThis() {\n"
                + "      return true;\n"
                + "   }\n"
                + "}\n"));
        performMove(src.getFileObject("t/SourceClass.java"), new int[]{1}, "t.TargetClass", Visibility.PUBLIC);
        verifyContent(src,
                new File("t/TargetClass.java", "package t;\n"
                + "import java.util.function.BooleanSupplier;\n"
                + "public class TargetClass {\n"
                + "   public static void doStuff(BooleanSupplier source) {\n"
                + "        boolean val = source.getAsBoolean();\n"
                + "    }\n"
                + "    public static void prepareStuff() {\n"
                + "       doStuff(TargetClass::moveThis);\n"
                + "    }\n"
                + "   public static boolean moveThis() {\n"
                + "      return true;\n"
                + "   }\n"
                + "}\n"),
                new File("t/SourceClass.java", "package t;\n"
                + "public class SourceClass {\n"
                + "}\n"));
    }

    public void testMoveMethodRef2() throws Exception {
        writeFilesAndWaitForScan(src,
                new File("t/TargetClass.java", "package t;\n"
                + "public class TargetClass {\n"
                + "    public static void main(String[] args) { \n"
                + "        // Referring non-static method  \n"
                + "       SourceClass obj = new SourceClass();  \n"
                + "       Sayable sayable = obj::saySomething;  \n"
                + "        sayable.say();  \n"
                + "    }\n"
                + "    interface Sayable{\n"
                + "    void say();  \n"
                + "} \n"
                + "}\n"),
                new File("t/SourceClass.java", "package t;\n"
                + "public class SourceClass {\n"
                + "  public  void saySomething() {\n"
                + "    }\n"
                + "}\n"));
        performMove(src.getFileObject("t/SourceClass.java"), new int[]{1}, "t.TargetClass", Visibility.PUBLIC, new Problem(false, "WRN_NoAccessor"));
        verifyContent(src,
                new File("t/TargetClass.java", "package t;\n"
                + "public class TargetClass {\n"
                + "    public static void main(String[] args) { \n"
                + "        // Referring non-static method  \n"
                + "       SourceClass obj = new SourceClass();  \n"
                + "       Sayable sayable = obj::saySomething;  \n"
                + "        sayable.say();  \n"
                + "    }\n"
                + "  public void saySomething() {\n"
                + "    }\n"
                + "    interface Sayable{\n"
                + "    void say();  \n"
                + "} \n"
                + "}\n"),
                new File("t/SourceClass.java", "package t;\n"
                + "public class SourceClass {\n"
                + "}\n"));
    }

    public void testMoveMethodRef3() throws Exception {
        writeFilesAndWaitForScan(src,
                new File("t/TargetClass.java", "package t;\n"
                + "public class TargetClass {\n"
                + "    public static void main(String[] args) { \n"
                + "        // Referring static method  \n"
                + "       Sayable sayable = SourceClass::saySomething;  \n"
                + "        sayable.say();  \n"
                + "    }\n"
                + "    interface Sayable{\n"
                + "    void say();  \n"
                + "} \n"
                + "}\n"),
                new File("t/SourceClass.java", "package t;\n"
                + "public class SourceClass {\n"
                + "  public  static void saySomething() {\n"
                + "    }\n"
                + "}\n"));
        performMove(src.getFileObject("t/SourceClass.java"), new int[]{1}, "t.TargetClass", Visibility.PUBLIC);
        verifyContent(src,
                new File("t/TargetClass.java", "package t;\n"
                + "public class TargetClass {\n"
                + "    public static void main(String[] args) { \n"
                + "        // Referring static method  \n"
                + "       Sayable sayable = TargetClass::saySomething;  \n"
                + "        sayable.say();  \n"
                + "    }\n"
                + "  public static void saySomething() {\n"
                + "    }\n"
                + "    interface Sayable{\n"
                + "    void say();  \n"
                + "} \n"
                + "}\n"),
                new File("t/SourceClass.java", "package t;\n"
                + "public class SourceClass {\n"
                + "}\n"));
    }
}
