Bug 410056: [1.8][move method] Moving default method brings up Textual Move wizard
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_1/in/A.java b/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_1/in/A.java
new file mode 100644
index 0000000..5229bec
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_1/in/A.java
@@ -0,0 +1,6 @@
+package p;
+public interface A{
+	default String getDefaultName(B b) {
+		return "Something";
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_1/in/B.java b/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_1/in/B.java
new file mode 100644
index 0000000..d110d65
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_1/in/B.java
@@ -0,0 +1,3 @@
+package p;
+class B{
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_1/out/A.java b/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_1/out/A.java
new file mode 100644
index 0000000..9ac9fa1
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_1/out/A.java
@@ -0,0 +1,3 @@
+package p;
+public interface A{
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_1/out/B.java b/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_1/out/B.java
new file mode 100644
index 0000000..4855b03
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_1/out/B.java
@@ -0,0 +1,7 @@
+package p;
+class B{
+
+	public String getDefaultName() {
+		return "Something";
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_2/in/A.java b/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_2/in/A.java
new file mode 100644
index 0000000..5229bec
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_2/in/A.java
@@ -0,0 +1,6 @@
+package p;
+public interface A{
+	default String getDefaultName(B b) {
+		return "Something";
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_2/in/B.java b/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_2/in/B.java
new file mode 100644
index 0000000..93910c8
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_2/in/B.java
@@ -0,0 +1,3 @@
+package p;
+interface B{
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_2/out/A.java b/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_2/out/A.java
new file mode 100644
index 0000000..9ac9fa1
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_2/out/A.java
@@ -0,0 +1,3 @@
+package p;
+public interface A{
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_2/out/B.java b/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_2/out/B.java
new file mode 100644
index 0000000..303f91c
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_2/out/B.java
@@ -0,0 +1,7 @@
+package p;
+interface B{
+
+	default String getDefaultName() {
+		return "Something";
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_3/in/A.java b/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_3/in/A.java
new file mode 100644
index 0000000..265ce9f
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_3/in/A.java
@@ -0,0 +1,23 @@
+package p1;
+
+import p2.B;
+
+public interface A {
+	public int fInt= 10;
+	public B fB= new B() {};
+	public String fString= "something";
+	public boolean fBool= true;
+	
+	/**
+	 * This is a comment
+	 * @param j
+	 * @param foo
+	 * @param bar
+	 */
+	public default void mA1(float j, int foo, String bar) {
+		System.out.println(bar + j + this);
+		String z= fString + fBool;
+	}
+	
+	public void mA2();
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_3/in/B.java b/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_3/in/B.java
new file mode 100644
index 0000000..53c1e5b
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_3/in/B.java
@@ -0,0 +1,5 @@
+package p2;
+
+public interface B {
+	
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_3/out/A.java b/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_3/out/A.java
new file mode 100644
index 0000000..9fce3f4
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_3/out/A.java
@@ -0,0 +1,12 @@
+package p1;
+
+import p2.B;
+
+public interface A {
+	public int fInt= 10;
+	public B fB= new B() {};
+	public String fString= "something";
+	public boolean fBool= true;
+	
+	public void mA2();
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_3/out/B.java b/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_3/out/B.java
new file mode 100644
index 0000000..f0eb937
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_3/out/B.java
@@ -0,0 +1,17 @@
+package p2;
+
+public interface B {
+
+	/**
+	 * This is a comment
+	 * @param a TODO
+	 * @param j
+	 * @param foo
+	 * @param bar
+	 */
+	public default void mA1(A a, float j, int foo, String bar) {
+		System.out.println(bar + j + a);
+		String z= A.fString + A.fBool;
+	}
+	
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_4/in/A.java b/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_4/in/A.java
new file mode 100644
index 0000000..0bb346b
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_4/in/A.java
@@ -0,0 +1,23 @@
+package p1;
+
+import p2.B;
+
+public interface A {
+	public int fInt= 10;
+	public B fB= new B();
+	public String fString= "something";
+	public boolean fBool= true;
+	
+	/**
+	 * This is a comment
+	 * @param j
+	 * @param foo
+	 * @param bar
+	 */
+	public default void mA1(float j, int foo, String bar) {
+		System.out.println(bar + j + this);
+		String z= fString + fBool;
+	}
+	
+	public void mA2();
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_4/in/B.java b/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_4/in/B.java
new file mode 100644
index 0000000..2350b78
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_4/in/B.java
@@ -0,0 +1,5 @@
+package p2;
+
+public class B {
+	
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_4/out/A.java b/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_4/out/A.java
new file mode 100644
index 0000000..a39cd9b
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_4/out/A.java
@@ -0,0 +1,12 @@
+package p1;
+
+import p2.B;
+
+public interface A {
+	public int fInt= 10;
+	public B fB= new B();
+	public String fString= "something";
+	public boolean fBool= true;
+	
+	public void mA2();
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_4/out/B.java b/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_4/out/B.java
new file mode 100644
index 0000000..e3a84e6
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/MoveInstanceMethod/canMove/test18_4/out/B.java
@@ -0,0 +1,17 @@
+package p2;
+
+public class B {
+
+	/**
+	 * This is a comment
+	 * @param a TODO
+	 * @param j
+	 * @param foo
+	 * @param bar
+	 */
+	public void mA1(A a, float j, int foo, String bar) {
+		System.out.println(bar + j + a);
+		String z= A.fString + A.fBool;
+	}
+	
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/AllRefactoringTests.java b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/AllRefactoringTests.java
index d79ff16..4a2f11c 100644
--- a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/AllRefactoringTests.java
+++ b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/AllRefactoringTests.java
@@ -74,6 +74,7 @@
 		suite.addTest(RenameStaticMethodTests.suite());
 		suite.addTest(RenameParametersTests.suite());
 		suite.addTest(MoveInstanceMethodTests.suite());
+		suite.addTest(MoveInstanceMethodTests18.suite());
 		suite.addTest(IntroduceIndirectionTests.suite());
 		suite.addTest(IntroduceIndirectionTests17.suite());
 		suite.addTest(IntroduceIndirectionTests18.suite());
diff --git a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/MoveInstanceMethodTests.java b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/MoveInstanceMethodTests.java
index fd0dae0..ca2eb77 100644
--- a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/MoveInstanceMethodTests.java
+++ b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/MoveInstanceMethodTests.java
@@ -242,7 +242,8 @@
 		}
 	}
 
-	private void helper1(String[] cuQNames, String selectionCuQName, int startLine, int startColumn, int endLine, int endColumn, int newReceiverType, String newReceiverName, boolean inlineDelegator, boolean removeDelegator) throws Exception {
+	protected void helper1(String[] cuQNames, String selectionCuQName, int startLine, int startColumn, int endLine, int endColumn, int newReceiverType, String newReceiverName,
+			boolean inlineDelegator, boolean removeDelegator) throws Exception {
 		int selectionCuIndex= firstIndexOf(selectionCuQName, cuQNames);
 		Assert.isTrue(selectionCuIndex != -1, "parameter selectionCuQName must match some String in cuQNames.");
 		helper1(cuQNames, selectionCuIndex, startLine, startColumn, endLine, endColumn, newReceiverType, newReceiverName, null, inlineDelegator, removeDelegator);
diff --git a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/MoveInstanceMethodTests18.java b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/MoveInstanceMethodTests18.java
new file mode 100644
index 0000000..f70ceb7
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/MoveInstanceMethodTests18.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2014 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.ui.tests.refactoring;
+
+import junit.framework.Test;
+
+public class MoveInstanceMethodTests18 extends MoveInstanceMethodTests {
+
+	private static final Class clazz= MoveInstanceMethodTests18.class;
+
+	public MoveInstanceMethodTests18(String name) {
+		super(name);
+	}
+
+	public static Test suite() {
+		return setUpTest(new NoSuperTestsSuite(clazz));
+	}
+
+	public static Test setUpTest(Test someTest) {
+		return new Java18Setup(someTest);
+	}
+
+	// test for bug 410056, move default method from interface to class
+	public void test18_1() throws Exception {
+		String[] cuQNames= new String[] { "p.A", "p.B" };
+		String selectionCuQName= "p.A";
+		helper1(cuQNames, selectionCuQName, 3, 20, 3, 34, PARAMETER, "b", true, true);
+
+	}
+
+	// test for bug 410056, move default method from interface to interface
+	public void test18_2() throws Exception {
+		String[] cuQNames= new String[] { "p.A", "p.B" };
+		String selectionCuQName= "p.A";
+		helper1(cuQNames, selectionCuQName, 3, 20, 3, 34, PARAMETER, "b", true, true);
+	}
+
+	// test for bug 410056, move default method from interface to interface(declared field)
+	public void test18_3() throws Exception {
+		String[] cuQNames= new String[] { "p.A", "p.B" };
+		String selectionCuQName= "p.A";
+		helper1(cuQNames, selectionCuQName, 17, 25, 17, 28, FIELD, "fB", true, true);
+	}
+
+	// test for bug 410056, move default method from interface to class(declared field)
+	public void test18_4() throws Exception {
+		String[] cuQNames= new String[] { "p.A", "p.B" };
+		String selectionCuQName= "p.A";
+		helper1(cuQNames, selectionCuQName, 17, 25, 17, 28, FIELD, "fB", true, true);
+	}
+}
diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/RefactoringAvailabilityTester.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/RefactoringAvailabilityTester.java
index 7f2f001..76d6f99 100644
--- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/RefactoringAvailabilityTester.java
+++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/RefactoringAvailabilityTester.java
@@ -829,7 +829,8 @@
 	}
 
 	public static boolean isMoveMethodAvailable(final IMethod method) throws JavaModelException {
-		return method.exists() && !method.isConstructor() && !method.isBinary() && !method.getDeclaringType().isInterface() && !method.isReadOnly() && !JdtFlags.isStatic(method);
+		return method.exists() && !method.isConstructor() && !method.isBinary() && !method.isReadOnly()
+				&& !JdtFlags.isStatic(method) && (JdtFlags.isDefaultMethod(method) || !method.getDeclaringType().isInterface());
 	}
 
 	public static boolean isMoveMethodAvailable(final IStructuredSelection selection) throws JavaModelException {
diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/MoveInstanceMethodProcessor.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/MoveInstanceMethodProcessor.java
index 1e6f0e7..423561e 100644
--- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/MoveInstanceMethodProcessor.java
+++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/MoveInstanceMethodProcessor.java
@@ -1476,7 +1476,7 @@
 			monitor.worked(1);
 			if (fMethod.getDeclaringType().isAnnotation())
 				status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_no_annotation, JavaStatusContext.create(fMethod)));
-			else if (fMethod.getDeclaringType().isInterface())
+			else if (fMethod.getDeclaringType().isInterface() && !Flags.isDefaultMethod(flags))
 				status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_no_interface, JavaStatusContext.create(fMethod)));
 			monitor.worked(1);
 		} finally {
@@ -1606,7 +1606,7 @@
 				ITypeBinding binding= null;
 				for (int index= 0; index < bindings.length; index++) {
 					binding= bindings[index].getType();
-					if ((binding.isClass() || binding.isEnum()) && binding.isFromSource()) {
+					if ((binding.isClass() || binding.isEnum() || is18OrHigherInterface(binding)) && binding.isFromSource()) {
 						possibleTargets.add(bindings[index]);
 						candidateTargets.add(bindings[index]);
 					}
@@ -1616,13 +1616,13 @@
 				bindings= visitor.getReadOnlyFields();
 				for (int index= 0; index < bindings.length; index++) {
 					binding= bindings[index].getType();
-					if (binding.isClass() && binding.isFromSource())
+					if ((binding.isClass() || is18OrHigherInterface(binding)) && binding.isFromSource())
 						possibleTargets.add(bindings[index]);
 				}
 				bindings= visitor.getDeclaredFields();
 				for (int index= 0; index < bindings.length; index++) {
 					binding= bindings[index].getType();
-					if (binding.isClass() && binding.isFromSource())
+					if ((binding.isClass() || is18OrHigherInterface(binding)) && binding.isFromSource())
 						candidateTargets.add(bindings[index]);
 				}
 			}
@@ -1634,6 +1634,13 @@
 		return fPossibleTargets;
 	}
 
+	private static boolean is18OrHigherInterface(ITypeBinding binding) {
+		if (!binding.isInterface() || binding.isAnnotation())
+			return false;
+		IJavaElement javaElement= binding.getJavaElement();
+		return javaElement != null && JavaModelUtil.is18OrHigher(javaElement.getJavaProject());
+	}
+
 	/**
 	 * Creates a visibility-adjusted target expression taking advantage of
 	 * existing accessor methods.
@@ -2281,9 +2288,18 @@
 				if (declaring != null && Bindings.equals(declaring.getPackage(), fTarget.getType().getPackage()))
 					same= true;
 				final Modifier.ModifierKeyword keyword= same ? null : Modifier.ModifierKeyword.PUBLIC_KEYWORD;
-				if (MemberVisibilityAdjustor.hasLowerVisibility(binding.getModifiers(), same ? Modifier.NONE : keyword == null ? Modifier.NONE : keyword.toFlagValue()) && MemberVisibilityAdjustor.needsVisibilityAdjustments(fMethod, keyword, adjustments)) {
+				ModifierRewrite modifierRewrite= ModifierRewrite.create(rewrite, declaration);
+				if (JdtFlags.isDefaultMethod(binding) && getTargetType().isClass()) {
+					// Remove 'default' modifier and add 'public' visibility
+					modifierRewrite.setVisibility(Modifier.PUBLIC, null);
+					modifierRewrite.setModifiers(Modifier.NONE, Modifier.DEFAULT, null);
+				} else if (!JdtFlags.isDefaultMethod(binding) && getTargetType().isInterface()) {
+					// Remove visibility modifiers and add 'default'
+					modifierRewrite.setModifiers(Modifier.DEFAULT, Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE, null);
+				} else if (MemberVisibilityAdjustor.hasLowerVisibility(binding.getModifiers(), same ? Modifier.NONE : keyword == null ? Modifier.NONE : keyword.toFlagValue())
+						&& MemberVisibilityAdjustor.needsVisibilityAdjustments(fMethod, keyword, adjustments)) {
 					final MemberVisibilityAdjustor.IncomingMemberVisibilityAdjustment adjustment= new MemberVisibilityAdjustor.IncomingMemberVisibilityAdjustment(fMethod, keyword, RefactoringStatus.createStatus(RefactoringStatus.WARNING, Messages.format(RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_method_warning, new String[] { MemberVisibilityAdjustor.getLabel(fMethod), MemberVisibilityAdjustor.getLabel(keyword) }), JavaStatusContext.create(fMethod), null, RefactoringStatusEntry.NO_CODE, null));
-					ModifierRewrite.create(rewrite, declaration).setVisibility(keyword == null ? Modifier.NONE : keyword.toFlagValue(), null);
+					modifierRewrite.setVisibility(keyword == null ? Modifier.NONE : keyword.toFlagValue(), null);
 					adjustment.setNeedsRewriting(false);
 					adjustments.put(fMethod, adjustment);
 				}