This is an automated email from the ASF dual-hosted git repository.

dbalek pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/netbeans.git


The following commit(s) were added to refs/heads/master by this push:
     new bd2d92c  LSP: Move refactoring added. (#3123)
bd2d92c is described below

commit bd2d92c51a3ec43c41820ef1214ea21105c550fb
Author: Dusan Balek <[email protected]>
AuthorDate: Thu Aug 26 09:41:14 2021 +0200

    LSP: Move refactoring added. (#3123)
    
    * LSP: Move refactoring added.
    * LSP: Rename refactoring modifies originating file only - fixed.
---
 .../refactoring/plugins/FileMovePlugin.java        |   2 +-
 .../java/hints/introduce/FieldValidator.java       |  30 +-
 .../java/hints/introduce/IntroduceConstantFix.java |  15 +-
 .../IntroduceExpressionBasedMethodFix.java         |  21 +-
 .../java/hints/introduce/IntroduceFieldFix.java    |  32 +-
 .../java/hints/introduce/IntroduceFixBase.java     |  12 +-
 .../java/hints/introduce/IntroduceHint.java        |  25 +-
 .../java/hints/introduce/IntroduceMethodFix.java   |  25 +-
 .../java/hints/introduce/IntroduceVariableFix.java |  22 +-
 .../java/hints/introduce/MethodValidator.java      |  21 +-
 ...CodeGenerator.java => CodeActionsProvider.java} |  35 +-
 .../lsp/server/protocol/ConstructorGenerator.java  |  14 +-
 .../server/protocol/DelegateMethodGenerator.java   |  14 +-
 .../server/protocol/EqualsHashCodeGenerator.java   |  14 +-
 .../lsp/server/protocol/GetterSetterGenerator.java |  13 +-
 .../protocol/ImplementOverrideMethodGenerator.java |  14 +-
 .../java/lsp/server/protocol/LoggerGenerator.java  |  14 +-
 .../java/lsp/server/protocol/MoveRefactoring.java  | 373 +++++++++++++++++++
 .../modules/java/lsp/server/protocol/Server.java   |   8 +-
 .../server/protocol/TextDocumentServiceImpl.java   |  96 ++---
 .../lsp/server/protocol/ToStringGenerator.java     |  14 +-
 .../lsp/server/protocol/WorkspaceServiceImpl.java  |   6 +-
 .../java/lsp/server/protocol/ServerTest.java       | 410 ++++++++++++++++++++-
 .../java/plugins/MoveFileRefactoringPlugin.java    |   1 +
 24 files changed, 1034 insertions(+), 197 deletions(-)

diff --git 
a/ide/refactoring.api/src/org/netbeans/modules/refactoring/plugins/FileMovePlugin.java
 
b/ide/refactoring.api/src/org/netbeans/modules/refactoring/plugins/FileMovePlugin.java
index 610c414..578ed02 100644
--- 
a/ide/refactoring.api/src/org/netbeans/modules/refactoring/plugins/FileMovePlugin.java
+++ 
b/ide/refactoring.api/src/org/netbeans/modules/refactoring/plugins/FileMovePlugin.java
@@ -80,7 +80,7 @@ public class FileMovePlugin implements RefactoringPlugin {
     public void cancelRequest() {
     }
     
-    private class MoveFile extends SimpleRefactoringElementImplementation {
+    public class MoveFile extends SimpleRefactoringElementImplementation {
         
         private FileObject fo;
         public MoveFile(FileObject fo, RefactoringElementsBag session) {
diff --git 
a/java/java.hints/src/org/netbeans/modules/java/hints/introduce/FieldValidator.java
 
b/java/java.hints/src/org/netbeans/modules/java/hints/introduce/FieldValidator.java
index 4b2a630..c94c0ab 100644
--- 
a/java/java.hints/src/org/netbeans/modules/java/hints/introduce/FieldValidator.java
+++ 
b/java/java.hints/src/org/netbeans/modules/java/hints/introduce/FieldValidator.java
@@ -25,10 +25,9 @@ import com.sun.source.tree.Tree;
 import com.sun.source.tree.TryTree;
 import com.sun.source.tree.VariableTree;
 import com.sun.source.util.TreePath;
-import java.io.IOException;
+import java.util.Collections;
 import java.util.Map;
 import javax.lang.model.element.Element;
-import javax.lang.model.element.ElementKind;
 import javax.lang.model.element.TypeElement;
 import javax.lang.model.type.DeclaredType;
 import javax.lang.model.type.TypeMirror;
@@ -37,16 +36,20 @@ import org.netbeans.api.java.source.CompilationInfo;
 import org.netbeans.api.java.source.ElementHandle;
 import org.netbeans.api.java.source.ElementUtilities.ElementAcceptor;
 import org.netbeans.api.java.source.JavaSource;
-import org.netbeans.api.java.source.Task;
 import org.netbeans.api.java.source.TreePathHandle;
 import org.netbeans.api.java.source.TypeMirrorHandle;
+import org.netbeans.modules.parsing.api.ParserManager;
+import org.netbeans.modules.parsing.api.ResultIterator;
+import org.netbeans.modules.parsing.api.Source;
+import org.netbeans.modules.parsing.api.UserTask;
+import org.netbeans.modules.parsing.spi.ParseException;
 
 /**
  *
  * @author sdedic
  */
 final class FieldValidator implements MemberValidator {
-    private final JavaSource            theSource;
+    private final Source            theSource;
     private final TypeMirrorHandle      fieldTypeHandle;
     private final TreePathHandle        srcHandle;
     
@@ -54,7 +57,7 @@ final class FieldValidator implements MemberValidator {
     private ElementHandle<Element>  target;
     private MemberSearchResult lastResult;
 
-    public FieldValidator(JavaSource theSource, TypeMirrorHandle 
fieldTypeHandle, TreePathHandle srcHandle) {
+    public FieldValidator(Source theSource, TypeMirrorHandle fieldTypeHandle, 
TreePathHandle srcHandle) {
         this.theSource = theSource;
         this.fieldTypeHandle = fieldTypeHandle;
         this.srcHandle = srcHandle;
@@ -71,15 +74,15 @@ final class FieldValidator implements MemberValidator {
         }
         SearchImpl impl = new SearchImpl(target, n);
         try {
-            theSource.runUserActionTask(impl, true);
-        } catch (IOException ex) {
+            ParserManager.parse(Collections.singleton(theSource), impl);
+        } catch (ParseException ex) {
            return null;
         }
         
         return lastResult;
     }
     
-    private class SearchImpl implements Task<CompilationController>, 
ElementAcceptor {
+    private class SearchImpl extends UserTask implements ElementAcceptor {
         private final TreePathHandle targetHandle;
         private final String name;
         
@@ -93,9 +96,10 @@ final class FieldValidator implements MemberValidator {
         }
         
         @Override
-        public void run(CompilationController parameter) throws Exception {
-            parameter.toPhase(JavaSource.Phase.RESOLVED);
-            this.cinfo = parameter;
+        public void run(ResultIterator resultIterator) throws Exception {
+            CompilationController cc = 
CompilationController.get(resultIterator.getParserResult());
+            cc.toPhase(JavaSource.Phase.RESOLVED);
+            this.cinfo = cc;
             if (targetHandle == null || srcHandle == null) {
                 return;
             }
@@ -109,7 +113,7 @@ final class FieldValidator implements MemberValidator {
             }
             initialScope = cinfo.getTrees().getScope(srcPath);
             Scope targetScope = cinfo.getTrees().getScope(targetPath);
-            Map<? extends Element, Scope> visibleVariables = 
+            Map<? extends Element, Scope> visibleVariables =
                     
cinfo.getElementUtilities().findElementsAndOrigins(initialScope, this);
             lastResult = null;
             Element target = cinfo.getTrees().getElement(targetPath);
@@ -216,7 +220,6 @@ final class FieldValidator implements MemberValidator {
                         }
                         break;
                     }
-                        
                 }
                 srcPath = srcPath.getParentPath();
             }
@@ -248,5 +251,4 @@ final class FieldValidator implements MemberValidator {
                    cinfo.getTrees().isAccessible(initialScope, e, 
(DeclaredType)type);
         }
     }
-    
 }
diff --git 
a/java/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceConstantFix.java
 
b/java/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceConstantFix.java
index a17230b..ef55b7f 100644
--- 
a/java/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceConstantFix.java
+++ 
b/java/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceConstantFix.java
@@ -22,7 +22,7 @@ import com.sun.source.tree.ClassTree;
 import com.sun.source.tree.IdentifierTree;
 import com.sun.source.tree.Tree;
 import com.sun.source.util.TreePath;
-import java.io.IOException;
+import java.util.Collections;
 import java.util.EnumSet;
 import java.util.concurrent.atomic.AtomicBoolean;
 import javax.lang.model.element.Element;
@@ -32,13 +32,14 @@ import javax.lang.model.type.TypeKind;
 import javax.swing.JButton;
 import org.netbeans.api.java.source.CodeStyle;
 import org.netbeans.api.java.source.CompilationInfo;
-import org.netbeans.api.java.source.JavaSource;
 import org.netbeans.api.java.source.ModificationResult;
 import org.netbeans.api.java.source.TreePathHandle;
 import org.netbeans.api.java.source.TreeUtilities;
 import org.netbeans.api.java.source.WorkingCopy;
 import org.netbeans.modules.java.hints.StopProcessing;
 import org.netbeans.modules.java.hints.errors.Utilities;
+import org.netbeans.modules.parsing.api.Source;
+import org.netbeans.modules.parsing.spi.ParseException;
 import org.openide.util.NbBundle;
 
 /**
@@ -104,7 +105,7 @@ public class IntroduceConstantFix extends IntroduceFieldFix 
{
         if (el == null || !(el.getKind().isClass() || 
el.getKind().isInterface())) {
             return null;
         }
-        IntroduceConstantFix fix = new IntroduceConstantFix(h, 
info.getJavaSource(), varName, numDuplicates, offset, 
TreePathHandle.create(constantTarget, info));
+        IntroduceConstantFix fix = new IntroduceConstantFix(h, 
info.getSnapshot().getSource(), varName, numDuplicates, offset, 
TreePathHandle.create(constantTarget, info));
         fix.setTargetIsInterface(clazz.getKind() == Tree.Kind.INTERFACE);
         return fix;
     }
@@ -135,8 +136,8 @@ public class IntroduceConstantFix extends IntroduceFieldFix 
{
         }
     }
 
-    public IntroduceConstantFix(TreePathHandle handle, JavaSource js, String 
guessedName, int numDuplicates, int offset, TreePathHandle target) {
-        super(handle, js, guessedName, numDuplicates, null, true, true, 
offset, true, target);
+    public IntroduceConstantFix(TreePathHandle handle, Source source, String 
guessedName, int numDuplicates, int offset, TreePathHandle target) {
+        super(handle, source, guessedName, numDuplicates, null, true, true, 
offset, true, target);
     }
 
     @Override
@@ -165,7 +166,7 @@ public class IntroduceConstantFix extends IntroduceFieldFix 
{
     }
 
     @Override
-    public ModificationResult getModificationResult() throws IOException {
-        return js.runModificationTask(new Worker(guessedName, 
permitDuplicates, true, EnumSet.of(Modifier.PRIVATE), 
IntroduceFieldPanel.INIT_FIELD, null, false));
+    public ModificationResult getModificationResult() throws ParseException {
+        return 
ModificationResult.runModificationTask(Collections.singleton(source), new 
Worker(guessedName, permitDuplicates, true, EnumSet.of(Modifier.PRIVATE), 
IntroduceFieldPanel.INIT_FIELD, null, false));
     }
 }
diff --git 
a/java/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceExpressionBasedMethodFix.java
 
b/java/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceExpressionBasedMethodFix.java
index 452ee25..5d95c25 100644
--- 
a/java/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceExpressionBasedMethodFix.java
+++ 
b/java/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceExpressionBasedMethodFix.java
@@ -28,7 +28,6 @@ import com.sun.source.tree.TypeParameterTree;
 import com.sun.source.tree.VariableTree;
 import com.sun.source.util.TreePath;
 import java.awt.GraphicsEnvironment;
-import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -49,7 +48,6 @@ import javax.swing.text.Document;
 import org.netbeans.api.java.source.CompilationInfo;
 import org.netbeans.api.java.source.JavaSource;
 import org.netbeans.api.java.source.ModificationResult;
-import org.netbeans.api.java.source.Task;
 import org.netbeans.api.java.source.TreeMaker;
 import org.netbeans.api.java.source.TreePathHandle;
 import org.netbeans.api.java.source.TreeUtilities;
@@ -59,6 +57,10 @@ import org.netbeans.api.java.source.matching.Matcher;
 import org.netbeans.api.java.source.matching.Occurrence;
 import org.netbeans.api.java.source.matching.Pattern;
 import org.netbeans.modules.java.hints.errors.Utilities;
+import org.netbeans.modules.parsing.api.ResultIterator;
+import org.netbeans.modules.parsing.api.Source;
+import org.netbeans.modules.parsing.api.UserTask;
+import org.netbeans.modules.parsing.spi.ParseException;
 import org.netbeans.spi.editor.hints.ChangeInfo;
 import org.netbeans.spi.editor.hints.Fix;
 import org.openide.DialogDescriptor;
@@ -156,8 +158,8 @@ final class IntroduceExpressionBasedMethodFix extends 
IntroduceFixBase implement
     private final List<TreePathHandle> typeVars;
     private final Collection<TargetDescription> targets;
 
-    public IntroduceExpressionBasedMethodFix(JavaSource js, TreePathHandle 
expression, List<TreePathHandle> parameters, TypeMirrorHandle returnType, 
Set<TypeMirrorHandle> thrownTypes, int duplicatesCount, List<TreePathHandle> 
typeVars, int offset, Collection<TargetDescription> targets) {
-        super(js, expression, duplicatesCount, offset);
+    public IntroduceExpressionBasedMethodFix(Source source, TreePathHandle 
expression, List<TreePathHandle> parameters, TypeMirrorHandle returnType, 
Set<TypeMirrorHandle> thrownTypes, int duplicatesCount, List<TreePathHandle> 
typeVars, int offset, Collection<TargetDescription> targets) {
+        super(source, expression, duplicatesCount, offset);
         this.parameters = parameters;
         this.thrownTypes = thrownTypes;
         this.typeVars = typeVars;
@@ -181,7 +183,7 @@ final class IntroduceExpressionBasedMethodFix extends 
IntroduceFixBase implement
         String caption = NbBundle.getMessage(IntroduceHint.class, 
"CAP_IntroduceMethod");
         DialogDescriptor dd = new DialogDescriptor(panel, caption, true, new 
Object[]{btnOk, btnCancel}, btnOk, DialogDescriptor.DEFAULT_ALIGN, null, null);
         NotificationLineSupport notifier = dd.createNotificationLineSupport();
-        MethodValidator val = new MethodValidator(js, parameters, returnType);
+        MethodValidator val = new MethodValidator(source, parameters, 
returnType);
         panel.setNotifier(notifier);
         panel.setValidator(val);
         panel.setOkButton(btnOk);
@@ -199,7 +201,7 @@ final class IntroduceExpressionBasedMethodFix extends 
IntroduceFixBase implement
     }
 
     @Override
-    public ModificationResult getModificationResult() throws IOException {
+    public ModificationResult getModificationResult() throws ParseException {
         ModificationResult result = null;
         int counter = 0;
         do {
@@ -212,9 +214,10 @@ final class IntroduceExpressionBasedMethodFix extends 
IntroduceFixBase implement
         return result;
     }
 
-    private ModificationResult getModificationResult(final String name, final 
TargetDescription target, final boolean replaceOther, final Set<Modifier> 
access, final boolean redoReferences, final MemberSearchResult searchResult) 
throws IOException {
-        return js.runModificationTask(new Task<WorkingCopy>() {
-            public void run(WorkingCopy copy) throws Exception {
+    private ModificationResult getModificationResult(final String name, final 
TargetDescription target, final boolean replaceOther, final Set<Modifier> 
access, final boolean redoReferences, final MemberSearchResult searchResult) 
throws ParseException {
+        return 
ModificationResult.runModificationTask(Collections.singleton(source), new 
UserTask() {
+            public void run(ResultIterator resultIterator) throws Exception {
+                WorkingCopy copy = 
WorkingCopy.get(resultIterator.getParserResult());
                 copy.toPhase(JavaSource.Phase.RESOLVED);
                 TreePath expression = 
IntroduceExpressionBasedMethodFix.this.handle.resolve(copy);
                 InstanceRefFinder finder = new InstanceRefFinder(copy, 
expression);
diff --git 
a/java/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceFieldFix.java
 
b/java/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceFieldFix.java
index a8a9f9c..d0b00b3 100644
--- 
a/java/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceFieldFix.java
+++ 
b/java/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceFieldFix.java
@@ -50,12 +50,15 @@ import javax.swing.text.BadLocationException;
 import org.netbeans.api.java.source.JavaSource;
 import org.netbeans.api.java.source.ModificationResult;
 import org.netbeans.api.java.source.SourceUtils;
-import org.netbeans.api.java.source.Task;
 import org.netbeans.api.java.source.TreeMaker;
 import org.netbeans.api.java.source.TreePathHandle;
 import org.netbeans.api.java.source.TreeUtilities;
 import org.netbeans.api.java.source.WorkingCopy;
 import org.netbeans.modules.java.hints.errors.Utilities;
+import org.netbeans.modules.parsing.api.ResultIterator;
+import org.netbeans.modules.parsing.api.Source;
+import org.netbeans.modules.parsing.api.UserTask;
+import org.netbeans.modules.parsing.spi.ParseException;
 import org.netbeans.spi.editor.hints.ChangeInfo;
 import org.netbeans.spi.editor.hints.Fix;
 import org.openide.DialogDescriptor;
@@ -86,14 +89,14 @@ class IntroduceFieldFix extends IntroduceFixBase implements 
Fix {
      * @param allowFinalInCurrentMethod false, if the variable may not be 
declared final
      * @param offset caret offset
      */
-    public IntroduceFieldFix(TreePathHandle handle, JavaSource js, String 
guessedName, 
+    public IntroduceFieldFix(TreePathHandle handle, Source source, String 
guessedName,
             int numDuplicates, int[] initilizeIn, boolean statik, boolean 
allowFinalInCurrentMethod, int offset, TreePathHandle target) {
-        this(handle, js, guessedName, numDuplicates, initilizeIn, statik, 
allowFinalInCurrentMethod, offset, false, target);
+        this(handle, source, guessedName, numDuplicates, initilizeIn, statik, 
allowFinalInCurrentMethod, offset, false, target);
     }
     
-    public IntroduceFieldFix(TreePathHandle handle, JavaSource js, String 
guessedName, 
+    public IntroduceFieldFix(TreePathHandle handle, Source source, String 
guessedName,
             int numDuplicates, int[] initilizeIn, boolean statik, boolean 
allowFinalInCurrentMethod, int offset, boolean allowDuplicates, TreePathHandle 
target) {
-        super(js, handle, numDuplicates, offset);
+        super(source, handle, numDuplicates, offset);
         this.guessedName = guessedName;
         this.initilizeIn = initilizeIn;
         this.statik = statik;
@@ -142,13 +145,13 @@ class IntroduceFieldFix extends IntroduceFixBase 
implements Fix {
     }
 
     @Override
-    public ChangeInfo implement() throws IOException, BadLocationException {
+    public ChangeInfo implement() throws IOException, BadLocationException, 
ParseException {
         JButton btnOk = new JButton(NbBundle.getMessage(IntroduceHint.class, 
"LBL_Ok"));
         
btnOk.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(IntroduceHint.class,
 "AD_IntrHint_OK"));
         JButton btnCancel = new 
JButton(NbBundle.getMessage(IntroduceHint.class, "LBL_Cancel"));
         
btnCancel.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(IntroduceHint.class,
 "AD_IntrHint_Cancel"));
         IntroduceFieldPanel panel = createPanel(btnOk);
-        FieldValidator fv = new FieldValidator(js, null, this.handle);
+        FieldValidator fv = new FieldValidator(source, null, this.handle);
         if (targetIsInterface) {
             panel.setAllowAccess(false);
         }
@@ -160,23 +163,21 @@ class IntroduceFieldFix extends IntroduceFixBase 
implements Fix {
         if (DialogDisplayer.getDefault().notify(dd) != btnOk) {
             return null; //cancel
         }
-        js.runModificationTask(new Worker(panel.getFieldName(), 
permitDuplicates && panel.isReplaceAll(),
-                panel.isDeclareFinal(), panel.getAccess(), 
panel.getInitializeIn(), 
-                fv.getLastResult(),
-                panel.isRefactorExisting())).commit();
+        ModificationResult.runModificationTask(Collections.singleton(source), 
new Worker(panel.getFieldName(), permitDuplicates && panel.isReplaceAll(),
+                panel.isDeclareFinal(), panel.getAccess(), 
panel.getInitializeIn(), fv.getLastResult(), 
panel.isRefactorExisting())).commit();
         return null;
     }
 
     @Override
-    public ModificationResult getModificationResult() throws IOException {
-        return js.runModificationTask(new Worker(guessedName, 
permitDuplicates, false, EnumSet.of(Modifier.PRIVATE), 
IntroduceFieldPanel.INIT_FIELD, null, false));
+    public ModificationResult getModificationResult() throws ParseException {
+        return 
ModificationResult.runModificationTask(Collections.singleton(source), new 
Worker(guessedName, permitDuplicates, false, EnumSet.of(Modifier.PRIVATE), 
IntroduceFieldPanel.INIT_FIELD, null, false));
     }
 
     /**
      * The actual modification. Some javac related data are recorded in 
fields, inner class prevents
      * unintentional leak if someone keeps a reference to the Fix
      */
-    protected final class Worker implements Task<WorkingCopy> {
+    protected final class Worker extends UserTask {
         final String name;
         final boolean replaceAll;
         final boolean declareFinal;
@@ -271,7 +272,8 @@ class IntroduceFieldFix extends IntroduceFixBase implements 
Fix {
         }
 
         @Override
-        public void run(WorkingCopy parameter) throws Exception {
+        public void run(ResultIterator resultIterator) throws Exception {
+            WorkingCopy parameter = 
WorkingCopy.get(resultIterator.getParserResult());
             parameter.toPhase(JavaSource.Phase.RESOLVED);
             TreePath resolved = handle.resolve(parameter);
             if (resolved == null) {
diff --git 
a/java/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceFixBase.java
 
b/java/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceFixBase.java
index 181affd..8d98d78 100644
--- 
a/java/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceFixBase.java
+++ 
b/java/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceFixBase.java
@@ -18,10 +18,10 @@
  */
 package org.netbeans.modules.java.hints.introduce;
 
-import java.io.IOException;
-import org.netbeans.api.java.source.JavaSource;
 import org.netbeans.api.java.source.ModificationResult;
 import org.netbeans.api.java.source.TreePathHandle;
+import org.netbeans.modules.parsing.api.Source;
+import org.netbeans.modules.parsing.spi.ParseException;
 import org.netbeans.spi.editor.hints.Fix;
 
 /**
@@ -32,14 +32,14 @@ import org.netbeans.spi.editor.hints.Fix;
 public abstract class IntroduceFixBase implements Fix {
 
     protected static final String TYPE_TAG = "typeTag";
-    protected final JavaSource js;
+    protected final Source source;
     protected final TreePathHandle  handle;
     protected final int duplicatesCount;
     protected final int offset;
     protected boolean targetIsInterface;
 
-    public IntroduceFixBase(JavaSource js, TreePathHandle handle, int 
duplicateCount, int offset) {
-        this.js = js;
+    public IntroduceFixBase(Source source, TreePathHandle handle, int 
duplicateCount, int offset) {
+        this.source = source;
         this.handle = handle;
         this.duplicatesCount = duplicateCount;
         this.offset = offset;
@@ -49,7 +49,7 @@ public abstract class IntroduceFixBase implements Fix {
         this.targetIsInterface = f;
     }
 
-    public abstract ModificationResult getModificationResult() throws 
IOException;
+    public abstract ModificationResult getModificationResult() throws 
ParseException;
 
     public int getNameOffset(ModificationResult result) {
         int[] span = result.getSpan(TYPE_TAG);
diff --git 
a/java/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceHint.java
 
b/java/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceHint.java
index 7d2a209..cba45fe 100644
--- 
a/java/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceHint.java
+++ 
b/java/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceHint.java
@@ -23,7 +23,6 @@ import com.sun.source.tree.CaseTree;
 import com.sun.source.tree.ClassTree;
 import com.sun.source.tree.ExpressionTree;
 import com.sun.source.tree.IdentifierTree;
-import com.sun.source.tree.LambdaExpressionTree;
 import com.sun.source.tree.MemberSelectTree;
 import com.sun.source.tree.MethodTree;
 import com.sun.source.tree.ModifiersTree;
@@ -40,7 +39,6 @@ import 
org.netbeans.api.java.source.support.ErrorAwareTreeScanner;
 import java.awt.Color;
 import java.awt.Rectangle;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.EnumMap;
@@ -48,8 +46,6 @@ import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.IdentityHashMap;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -64,10 +60,8 @@ import javax.lang.model.element.Name;
 import javax.lang.model.element.TypeElement;
 import javax.lang.model.element.VariableElement;
 import javax.lang.model.type.ErrorType;
-import javax.lang.model.type.ExecutableType;
 import javax.lang.model.type.TypeKind;
 import javax.lang.model.type.TypeMirror;
-import javax.lang.model.util.ElementFilter;
 import javax.swing.SwingUtilities;
 import javax.swing.text.AttributeSet;
 import javax.swing.text.BadLocationException;
@@ -79,8 +73,6 @@ import org.netbeans.api.editor.settings.AttributesUtilities;
 import org.netbeans.api.java.source.CancellableTask;
 import org.netbeans.api.java.source.CodeStyle;
 import org.netbeans.api.java.source.CompilationInfo;
-import org.netbeans.api.java.source.ElementHandle;
-import org.netbeans.api.java.source.ElementUtilities.ElementAcceptor;
 import org.netbeans.api.java.source.SourceUtils;
 import org.netbeans.api.java.source.TreeMaker;
 import org.netbeans.api.java.source.TreePathHandle;
@@ -254,13 +246,10 @@ public class IntroduceHint implements 
CancellableTask<CompilationInfo> {
         if (guessedName == null) guessedName = "name"; // NOI18N
         Scope s = info.getTrees().getScope(resolved);
         CodeStyle cs = CodeStyle.getDefault(info.getFileObject());
-        Fix variable = isVariable ? new IntroduceVariableFix(h, 
info.getJavaSource(), 
-                variableRewrite ? 
-                        guessedName : 
-                        Utilities.makeNameUnique(info, s, guessedName, 
cs.getLocalVarNamePrefix(), cs.getLocalVarNameSuffix()), 
+        Fix variable = isVariable ? new IntroduceVariableFix(h, 
info.getSnapshot().getSource(),
+                variableRewrite ? guessedName : Utilities.makeNameUnique(info, 
s, guessedName, cs.getLocalVarNamePrefix(), cs.getLocalVarNameSuffix()),
                 duplicatesForVariable.size() + 1, 
IntroduceKind.CREATE_VARIABLE, TreePathHandle.create(method, info), end) : null;
-        Fix constant = IntroduceConstantFix.createConstant(resolved, info, 
value, guessedName, 
-                        duplicatesForConstant.size() + 1, end, 
variableRewrite, cancel);
+        Fix constant = IntroduceConstantFix.createConstant(resolved, info, 
value, guessedName, duplicatesForConstant.size() + 1, end, variableRewrite, 
cancel);
 
 
         Fix parameter = isVariable ? new IntroduceParameterFix(h) : null;
@@ -297,7 +286,7 @@ public class IntroduceHint implements 
CancellableTask<CompilationInfo> {
             }
             Element el = info.getTrees().getElement(pathToClass);
             if (pathToClass != null && el != null && (el.getKind().isClass() 
|| el.getKind().isInterface())) {
-                field = new IntroduceFieldFix(h, info.getJavaSource(), 
guessedName, duplicatesForConstant.size() + 1, initilizeIn, 
+                field = new IntroduceFieldFix(h, 
info.getSnapshot().getSource(), guessedName, duplicatesForConstant.size() + 1, 
initilizeIn,
                         statik, allowFinalInCurrentMethod, end, 
!variableRewrite, TreePathHandle.create(pathToClass, info));
             }
 
@@ -354,10 +343,8 @@ public class IntroduceHint implements 
CancellableTask<CompilationInfo> {
                                 
Utilities.convertIfAnonymous(Utilities.resolveCapturedType(info, 
                                         resolveType(info, resolved)));
                         if (Utilities.isValidType(returnType)) {
-                            methodFix = new 
IntroduceExpressionBasedMethodFix(info.getJavaSource(), 
-                                    h, params, 
TypeMirrorHandle.create(returnType), 
-                                    exceptionHandles, duplicatesCount, 
typeVars, end, 
-                                    viableTargets);
+                            methodFix = new 
IntroduceExpressionBasedMethodFix(info.getSnapshot().getSource(), h, params, 
TypeMirrorHandle.create(returnType),
+                                    exceptionHandles, duplicatesCount, 
typeVars, end, viableTargets);
                             methodFix.setTargetIsInterface(allIfaces.get());
                         }
                     }
diff --git 
a/java/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceMethodFix.java
 
b/java/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceMethodFix.java
index 0e4fc7c..0a50a91 100644
--- 
a/java/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceMethodFix.java
+++ 
b/java/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceMethodFix.java
@@ -36,7 +36,6 @@ import com.sun.source.tree.VariableTree;
 import com.sun.source.util.SourcePositions;
 import com.sun.source.util.TreePath;
 import java.awt.GraphicsEnvironment;
-import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -67,7 +66,6 @@ import org.netbeans.api.java.source.CompilationInfo;
 import org.netbeans.api.java.source.GeneratorUtilities;
 import org.netbeans.api.java.source.JavaSource;
 import org.netbeans.api.java.source.ModificationResult;
-import org.netbeans.api.java.source.Task;
 import org.netbeans.api.java.source.TreeMaker;
 import org.netbeans.api.java.source.TreePathHandle;
 import org.netbeans.api.java.source.TreeUtilities;
@@ -77,6 +75,10 @@ import org.netbeans.api.java.source.matching.Matcher;
 import org.netbeans.api.java.source.matching.Occurrence;
 import org.netbeans.api.java.source.matching.Pattern;
 import org.netbeans.modules.java.hints.errors.Utilities;
+import org.netbeans.modules.parsing.api.ResultIterator;
+import org.netbeans.modules.parsing.api.Source;
+import org.netbeans.modules.parsing.api.UserTask;
+import org.netbeans.modules.parsing.spi.ParseException;
 import org.netbeans.spi.editor.hints.ChangeInfo;
 import org.netbeans.spi.editor.hints.Fix;
 import org.openide.DialogDescriptor;
@@ -275,7 +277,7 @@ public final class IntroduceMethodFix extends 
IntroduceFixBase implements Fix {
         List<TargetDescription> viableTargets = 
IntroduceExpressionBasedMethodFix.computeViableTargets(info, block, 
statementsToWrap, duplicates, cancel, allIfaces);
         IntroduceMethodFix imf = null;
         if (viableTargets != null && !viableTargets.isEmpty()) {
-            imf = new IntroduceMethodFix(info.getJavaSource(), h, params, 
additionaLocalTypes, additionaLocalNames, TypeMirrorHandle.create(returnType), 
returnAssignTo, declareVariableForReturnValue, exceptionHandles, exits, 
exitsFromAllBranches, statements[0], statements[1], 
+            imf = new IntroduceMethodFix(info.getSnapshot().getSource(), h, 
params, additionaLocalTypes, additionaLocalNames, 
TypeMirrorHandle.create(returnType), returnAssignTo, 
declareVariableForReturnValue, exceptionHandles, exits, exitsFromAllBranches, 
statements[0], statements[1],
                     duplicatesCount, scanner.getUsedTypeVars(), end, 
viableTargets);
             imf.setTargetIsInterface(allIfaces.get());
         }
@@ -389,8 +391,8 @@ public final class IntroduceMethodFix extends 
IntroduceFixBase implements Fix {
     private final List<TreePathHandle> typeVars;
     private final Collection<TargetDescription> targets;
 
-    public IntroduceMethodFix(JavaSource js, TreePathHandle parentBlock, 
List<TreePathHandle> parameters, List<TypeMirrorHandle> additionalLocalTypes, 
List<String> additionalLocalNames, TypeMirrorHandle returnType, TreePathHandle 
returnAssignTo, boolean declareVariableForReturnValue, Set<TypeMirrorHandle> 
thrownTypes, List<TreePathHandle> exists, boolean exitsFromAllBranches, int 
from, int to, int duplicatesCount, List<TreePathHandle> typeVars, int offset, 
Collection<TargetDescription> t [...]
-        super(js, parentBlock, duplicatesCount, offset);
+    public IntroduceMethodFix(Source source, TreePathHandle parentBlock, 
List<TreePathHandle> parameters, List<TypeMirrorHandle> additionalLocalTypes, 
List<String> additionalLocalNames, TypeMirrorHandle returnType, TreePathHandle 
returnAssignTo, boolean declareVariableForReturnValue, Set<TypeMirrorHandle> 
thrownTypes, List<TreePathHandle> exists, boolean exitsFromAllBranches, int 
from, int to, int duplicatesCount, List<TreePathHandle> typeVars, int offset, 
Collection<TargetDescription> t [...]
+        super(source, parentBlock, duplicatesCount, offset);
         this.parameters = parameters;
         this.additionalLocalTypes = additionalLocalTypes;
         this.additionalLocalNames = additionalLocalNames;
@@ -421,7 +423,7 @@ public final class IntroduceMethodFix extends 
IntroduceFixBase implements Fix {
         String caption = NbBundle.getMessage(IntroduceHint.class, 
"CAP_IntroduceMethod");
         DialogDescriptor dd = new DialogDescriptor(panel, caption, true, new 
Object[]{btnOk, btnCancel}, btnOk, DialogDescriptor.DEFAULT_ALIGN, null, null);
         NotificationLineSupport notifier = dd.createNotificationLineSupport();
-        MethodValidator val = new MethodValidator(js, parameters, returnType);
+        MethodValidator val = new MethodValidator(source, parameters, 
returnType);
         panel.setNotifier(notifier);
         panel.setValidator(val);
         panel.setOkButton(btnOk);
@@ -433,17 +435,17 @@ public final class IntroduceMethodFix extends 
IntroduceFixBase implements Fix {
         final Set<Modifier> access = panel.getAccess();
         final boolean replaceOther = panel.getReplaceOther();
         final TargetDescription target = panel.getSelectedTarget();
-        js.runModificationTask(new TaskImpl(access, name, target, 
replaceOther, val.getResult(), redoReferences)).commit();
+        ModificationResult.runModificationTask(Collections.singleton(source), 
new TaskImpl(access, name, target, replaceOther, val.getResult(), 
redoReferences)).commit();
         return null;
     }
 
     @Override
-    public ModificationResult getModificationResult() throws IOException {
+    public ModificationResult getModificationResult() throws ParseException {
         ModificationResult result = null;
         int counter = 0;
         do {
             try {
-                result = js.runModificationTask(new 
TaskImpl(EnumSet.of(Modifier.PRIVATE), "method" + (counter != 0 ? 
String.valueOf(counter) : ""), targets.iterator().next(), true, null, false));
+                result = 
ModificationResult.runModificationTask(Collections.singleton(source), new 
TaskImpl(EnumSet.of(Modifier.PRIVATE), "method" + (counter != 0 ? 
String.valueOf(counter) : ""), targets.iterator().next(), true, null, false));
             } catch (Exception e) {
                 counter++;
             }
@@ -471,7 +473,7 @@ public final class IntroduceMethodFix extends 
IntroduceFixBase implements Fix {
         
     }
 
-    private class TaskImpl implements Task<WorkingCopy> {
+    private class TaskImpl extends UserTask {
         private final Set<Modifier> access;
         private final String name;
         private final TargetDescription target;
@@ -792,7 +794,8 @@ public final class IntroduceMethodFix extends 
IntroduceFixBase implements Fix {
             return dupeRealArguments;
         }
 
-        public void run(WorkingCopy copy) throws Exception {
+        public void run(ResultIterator resultIterator) throws Exception {
+            WorkingCopy copy = 
WorkingCopy.get(resultIterator.getParserResult());
             copy.toPhase(JavaSource.Phase.RESOLVED);
             this.copy = copy;
             
diff --git 
a/java/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceVariableFix.java
 
b/java/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceVariableFix.java
index 6e40a51..bb65ec8 100644
--- 
a/java/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceVariableFix.java
+++ 
b/java/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceVariableFix.java
@@ -43,11 +43,14 @@ import org.netbeans.api.java.source.GeneratorUtilities;
 import org.netbeans.api.java.source.JavaSource;
 import org.netbeans.api.java.source.ModificationResult;
 import org.netbeans.api.java.source.SourceUtils;
-import org.netbeans.api.java.source.Task;
 import org.netbeans.api.java.source.TreeMaker;
 import org.netbeans.api.java.source.TreePathHandle;
 import org.netbeans.api.java.source.WorkingCopy;
 import org.netbeans.modules.java.hints.errors.Utilities;
+import org.netbeans.modules.parsing.api.ResultIterator;
+import org.netbeans.modules.parsing.api.Source;
+import org.netbeans.modules.parsing.api.UserTask;
+import org.netbeans.modules.parsing.spi.ParseException;
 import org.netbeans.spi.editor.hints.ChangeInfo;
 import org.netbeans.spi.editor.hints.Fix;
 import org.openide.DialogDescriptor;
@@ -102,9 +105,9 @@ final class IntroduceVariableFix extends IntroduceFixBase 
implements Fix {
     private final String guessedName;
     private final TreePathHandle targetHandle;
 
-    public IntroduceVariableFix(TreePathHandle handle, JavaSource js, String 
guessedName, int numDuplicates, IntroduceKind kind, 
+    public IntroduceVariableFix(TreePathHandle handle, Source source, String 
guessedName, int numDuplicates, IntroduceKind kind,
             TreePathHandle methodHandle, int offset) {
-        super(js, handle, numDuplicates, offset);
+        super(source, handle, numDuplicates, offset);
         this.guessedName = guessedName;
         this.targetHandle = methodHandle;
     }
@@ -122,7 +125,7 @@ final class IntroduceVariableFix extends IntroduceFixBase 
implements Fix {
         return NbBundle.getMessage(IntroduceHint.class, "FIX_" + getKeyExt()); 
//NOI18N
     }
 
-    public ChangeInfo implement() throws IOException, BadLocationException {
+    public ChangeInfo implement() throws IOException, BadLocationException, 
ParseException {
         JButton btnOk = new JButton(NbBundle.getMessage(IntroduceHint.class, 
"LBL_Ok"));
         JButton btnCancel = new 
JButton(NbBundle.getMessage(IntroduceHint.class, "LBL_Cancel"));
         IntroduceFieldPanel panel = new IntroduceFieldPanel(guessedName, null, 
duplicatesCount,
@@ -131,7 +134,7 @@ final class IntroduceVariableFix extends IntroduceFixBase 
implements Fix {
                 "introduceVariable", btnOk);
         String caption = NbBundle.getMessage(IntroduceHint.class, "CAP_" + 
getKeyExt()); //NOI18N
         DialogDescriptor dd = new DialogDescriptor(panel, caption, true, new 
Object[]{btnOk, btnCancel}, btnOk, DialogDescriptor.DEFAULT_ALIGN, null, null);
-        FieldValidator val = new FieldValidator(js, null, this.handle);
+        FieldValidator val = new FieldValidator(source, null, this.handle);
         panel.setNotifier(dd.createNotificationLineSupport());
         panel.setValidator(val);
         panel.setTarget(targetHandle);
@@ -148,13 +151,14 @@ final class IntroduceVariableFix extends IntroduceFixBase 
implements Fix {
     }
 
     @Override
-    public ModificationResult getModificationResult() throws IOException {
+    public ModificationResult getModificationResult() throws ParseException {
         return getModificationResult(true, guessedName, false, false, null);
     }
 
-    private ModificationResult getModificationResult(final boolean replaceAll, 
final String name, final boolean declareFinal, final boolean refactor, final 
MemberSearchResult search) throws IOException {
-        return js.runModificationTask(new Task<WorkingCopy>() {
-            public void run(WorkingCopy parameter) throws Exception {
+    private ModificationResult getModificationResult(final boolean replaceAll, 
final String name, final boolean declareFinal, final boolean refactor, final 
MemberSearchResult search) throws ParseException {
+        return 
ModificationResult.runModificationTask(Collections.singleton(source), new 
UserTask() {
+            public void run(ResultIterator resultIterator) throws Exception {
+                WorkingCopy parameter = 
WorkingCopy.get(resultIterator.getParserResult());
                 parameter.toPhase(JavaSource.Phase.RESOLVED);
                 TreePath resolved = handle.resolve(parameter);
                 if (resolved == null) {
diff --git 
a/java/java.hints/src/org/netbeans/modules/java/hints/introduce/MethodValidator.java
 
b/java/java.hints/src/org/netbeans/modules/java/hints/introduce/MethodValidator.java
index 4bb899c..7bf79a5 100644
--- 
a/java/java.hints/src/org/netbeans/modules/java/hints/introduce/MethodValidator.java
+++ 
b/java/java.hints/src/org/netbeans/modules/java/hints/introduce/MethodValidator.java
@@ -20,9 +20,9 @@ package org.netbeans.modules.java.hints.introduce;
 
 import com.sun.source.tree.Scope;
 import com.sun.source.util.TreePath;
-import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
@@ -41,9 +41,13 @@ import org.netbeans.api.java.source.CompilationInfo;
 import org.netbeans.api.java.source.ElementHandle;
 import org.netbeans.api.java.source.ElementUtilities.ElementAcceptor;
 import org.netbeans.api.java.source.JavaSource;
-import org.netbeans.api.java.source.Task;
 import org.netbeans.api.java.source.TreePathHandle;
 import org.netbeans.api.java.source.TypeMirrorHandle;
+import org.netbeans.modules.parsing.api.ParserManager;
+import org.netbeans.modules.parsing.api.ResultIterator;
+import org.netbeans.modules.parsing.api.Source;
+import org.netbeans.modules.parsing.api.UserTask;
+import org.netbeans.modules.parsing.spi.ParseException;
 
 /**
  * Validates that method is not in conflict with other one, or that it does 
not shadow
@@ -54,12 +58,12 @@ import org.netbeans.api.java.source.TypeMirrorHandle;
 final class MethodValidator implements MemberValidator {
     private TreePathHandle          target;
     private String                              name;
-    private final JavaSource  theSource;
+    private final Source  theSource;
     private final List<TreePathHandle> parameters;
     private final TypeMirrorHandle     returnType;
     private MemberSearchResult result;
     
-    public MethodValidator(JavaSource theSource, List<TreePathHandle> 
parameters, TypeMirrorHandle returnType) {
+    public MethodValidator(Source theSource, List<TreePathHandle> parameters, 
TypeMirrorHandle returnType) {
         this.theSource = theSource;
         this.parameters = parameters;
         this.returnType = returnType;
@@ -74,8 +78,8 @@ final class MethodValidator implements MemberValidator {
         if (!(type.equals(target) && n.equals(name))) {
             SearchWorker wrk = new SearchWorker(type, n);
             try {
-                theSource.runUserActionTask(wrk, true);
-            } catch (IOException ex) {
+                ParserManager.parse(Collections.singleton(theSource), wrk);
+            } catch (ParseException ex) {
             }
             this.result = wrk.result;
             this.name = n;
@@ -83,7 +87,7 @@ final class MethodValidator implements MemberValidator {
         return result;
     }
     
-    private class SearchWorker implements Task<CompilationController>, 
ElementAcceptor {
+    private class SearchWorker extends UserTask implements ElementAcceptor {
         private final TreePathHandle  targetHandle;
         private final String name;
         private MemberSearchResult result;
@@ -102,7 +106,8 @@ final class MethodValidator implements MemberValidator {
         }
         
         @Override
-        public void run(CompilationController parameter) throws Exception {
+        public void run(ResultIterator resultIterator) throws Exception {
+            CompilationController parameter = 
CompilationController.get(resultIterator.getParserResult());
             parameter.toPhase(JavaSource.Phase.RESOLVED);
             this.cinfo = parameter;
             TreePath targetPath = targetHandle.resolve(cinfo);
diff --git 
a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/CodeGenerator.java
 
b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/CodeActionsProvider.java
similarity index 87%
rename from 
java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/CodeGenerator.java
rename to 
java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/CodeActionsProvider.java
index 9c741f8..61380d7 100644
--- 
a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/CodeGenerator.java
+++ 
b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/CodeActionsProvider.java
@@ -43,17 +43,18 @@ import org.netbeans.api.java.source.CompilationInfo;
 import org.netbeans.api.java.source.ElementHandle;
 import org.netbeans.modules.editor.java.Utilities;
 import org.netbeans.modules.java.source.ElementHandleAccessor;
+import org.netbeans.modules.parsing.api.ResultIterator;
 
 /**
  *
  * @author Dusan Balek
  */
-public abstract class CodeGenerator {
+public abstract class CodeActionsProvider {
 
     public static final String CODE_GENERATOR_KIND = "source.generate";
     protected static final String ERROR = "<error>"; //NOI18N
 
-    public abstract List<CodeAction> getCodeActions(CompilationInfo info, 
CodeActionParams params);
+    public abstract List<CodeAction> getCodeActions(ResultIterator 
resultIterator, CodeActionParams params) throws Exception;
 
     public abstract Set<String> getCommands();
 
@@ -71,6 +72,24 @@ public abstract class CodeGenerator {
         return action;
     }
 
+    protected static String createLabel(CompilationInfo info, Element e) {
+        switch (e.getKind()) {
+            case ANNOTATION_TYPE:
+            case CLASS:
+            case ENUM:
+            case INTERFACE:
+                return createLabel(info, (TypeElement) e);
+            case CONSTRUCTOR:
+            case METHOD:
+                return createLabel(info, (ExecutableElement) e);
+            case ENUM_CONSTANT:
+            case FIELD:
+                return createLabel(info, (VariableElement) e);
+            default:
+                return null;
+        }
+    }
+
     protected static String createLabel(CompilationInfo info, TypeElement e) {
         StringBuilder sb = new StringBuilder();
         sb.append(e.getSimpleName());
@@ -153,14 +172,20 @@ public abstract class CodeGenerator {
         }
 
         public ElementData(Element element) {
-            ElementHandle<Element> handle = ElementHandle.create(element);
+            this(ElementHandle.create(element));
+        }
+
+        public ElementData(ElementHandle<? extends Element> handle) {
             this.kind = handle.getKind().name();
             this.signature = 
ElementHandleAccessor.getInstance().getJVMSignature(handle);
         }
 
+        ElementHandle toHandle() {
+            return 
ElementHandleAccessor.getInstance().create(ElementKind.valueOf(kind), 
signature);
+        }
+
         Element resolve(CompilationInfo info) {
-            ElementHandle handle = 
ElementHandleAccessor.getInstance().create(ElementKind.valueOf(kind), 
signature);
-            return handle.resolve(info);
+            return toHandle().resolve(info);
         }
 
         @Pure
diff --git 
a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/ConstructorGenerator.java
 
b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/ConstructorGenerator.java
index dccbd0d..7086bdd 100644
--- 
a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/ConstructorGenerator.java
+++ 
b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/ConstructorGenerator.java
@@ -51,11 +51,12 @@ import org.eclipse.lsp4j.MessageParams;
 import org.eclipse.lsp4j.MessageType;
 import org.eclipse.lsp4j.TextEdit;
 import org.eclipse.lsp4j.WorkspaceEdit;
-import org.netbeans.api.java.source.CompilationInfo;
+import org.netbeans.api.java.source.CompilationController;
 import org.netbeans.api.java.source.JavaSource;
 import org.netbeans.api.java.source.TreeUtilities;
 import org.netbeans.modules.java.editor.codegen.GeneratorUtils;
 import org.netbeans.modules.java.lsp.server.Utils;
+import org.netbeans.modules.parsing.api.ResultIterator;
 import org.openide.filesystems.FileObject;
 import org.openide.util.NbBundle;
 import org.openide.util.lookup.ServiceProvider;
@@ -64,8 +65,8 @@ import org.openide.util.lookup.ServiceProvider;
  *
  * @author Dusan Balek
  */
-@ServiceProvider(service = CodeGenerator.class, position = 10)
-public final class ConstructorGenerator extends CodeGenerator {
+@ServiceProvider(service = CodeActionsProvider.class, position = 10)
+public final class ConstructorGenerator extends CodeActionsProvider {
 
     public static final String GENERATE_CONSTRUCTOR =  
"java.generate.constructor";
 
@@ -79,7 +80,12 @@ public final class ConstructorGenerator extends 
CodeGenerator {
     @NbBundle.Messages({
         "DN_GenerateConstructor=Generate Constructor...",
     })
-    public List<CodeAction> getCodeActions(CompilationInfo info, 
CodeActionParams params) {
+    public List<CodeAction> getCodeActions(ResultIterator resultIterator, 
CodeActionParams params) throws Exception {
+        CompilationController info = 
CompilationController.get(resultIterator.getParserResult());
+        if (info == null) {
+            return Collections.emptyList();
+        }
+        info.toPhase(JavaSource.Phase.RESOLVED);
         List<String> only = params.getContext().getOnly();
         boolean isSource = only != null && 
only.contains(CodeActionKind.Source);
         int startOffset = getOffset(info, params.getRange().getStart());
diff --git 
a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/DelegateMethodGenerator.java
 
b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/DelegateMethodGenerator.java
index d59cec4..6f605b1 100644
--- 
a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/DelegateMethodGenerator.java
+++ 
b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/DelegateMethodGenerator.java
@@ -49,11 +49,12 @@ import org.eclipse.lsp4j.MessageParams;
 import org.eclipse.lsp4j.MessageType;
 import org.eclipse.lsp4j.TextEdit;
 import org.eclipse.lsp4j.WorkspaceEdit;
-import org.netbeans.api.java.source.CompilationInfo;
+import org.netbeans.api.java.source.CompilationController;
 import org.netbeans.api.java.source.ElementUtilities;
 import org.netbeans.api.java.source.JavaSource;
 import org.netbeans.api.java.source.TreeUtilities;
 import org.netbeans.modules.java.lsp.server.Utils;
+import org.netbeans.modules.parsing.api.ResultIterator;
 import org.openide.filesystems.FileObject;
 import org.openide.util.NbBundle;
 import org.openide.util.lookup.ServiceProvider;
@@ -62,8 +63,8 @@ import org.openide.util.lookup.ServiceProvider;
  *
  * @author Dusan Balek
  */
-@ServiceProvider(service = CodeGenerator.class, position = 60)
-public final class DelegateMethodGenerator extends CodeGenerator {
+@ServiceProvider(service = CodeActionsProvider.class, position = 60)
+public final class DelegateMethodGenerator extends CodeActionsProvider {
 
     public static final String GENERATE_DELEGATE_METHOD =  
"java.generate.delegateMethod";
 
@@ -77,11 +78,16 @@ public final class DelegateMethodGenerator extends 
CodeGenerator {
     @NbBundle.Messages({
         "DN_GenerateDelegateMethod=Generate Delegate Method...",
     })
-    public List<CodeAction> getCodeActions(CompilationInfo info, 
CodeActionParams params) {
+    public List<CodeAction> getCodeActions(ResultIterator resultIterator, 
CodeActionParams params) throws Exception {
         List<String> only = params.getContext().getOnly();
         if (only == null || !only.contains(CodeActionKind.Source)) {
             return Collections.emptyList();
         }
+        CompilationController info = 
CompilationController.get(resultIterator.getParserResult());
+        if (info == null) {
+            return Collections.emptyList();
+        }
+        info.toPhase(JavaSource.Phase.RESOLVED);
         int offset = getOffset(info, params.getRange().getStart());
         TreePath tp = info.getTreeUtilities().pathFor(offset);
         tp = 
info.getTreeUtilities().getPathElementOfKind(TreeUtilities.CLASS_TREE_KINDS, 
tp);
diff --git 
a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/EqualsHashCodeGenerator.java
 
b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/EqualsHashCodeGenerator.java
index 45fb6d3..67a981b 100644
--- 
a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/EqualsHashCodeGenerator.java
+++ 
b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/EqualsHashCodeGenerator.java
@@ -44,9 +44,10 @@ import org.eclipse.lsp4j.MessageParams;
 import org.eclipse.lsp4j.MessageType;
 import org.eclipse.lsp4j.TextEdit;
 import org.eclipse.lsp4j.WorkspaceEdit;
-import org.netbeans.api.java.source.CompilationInfo;
+import org.netbeans.api.java.source.CompilationController;
 import org.netbeans.api.java.source.JavaSource;
 import org.netbeans.modules.java.lsp.server.Utils;
+import org.netbeans.modules.parsing.api.ResultIterator;
 import org.openide.filesystems.FileObject;
 import org.openide.util.NbBundle;
 import org.openide.util.lookup.ServiceProvider;
@@ -55,8 +56,8 @@ import org.openide.util.lookup.ServiceProvider;
  *
  * @author Dusan Balek
  */
-@ServiceProvider(service = CodeGenerator.class, position = 40)
-public final class EqualsHashCodeGenerator extends CodeGenerator {
+@ServiceProvider(service = CodeActionsProvider.class, position = 40)
+public final class EqualsHashCodeGenerator extends CodeActionsProvider {
 
     public static final String GENERATE_EQUALS =  "java.generate.equals";
     public static final String GENERATE_HASH_CODE =  "java.generate.hashCode";
@@ -74,11 +75,16 @@ public final class EqualsHashCodeGenerator extends 
CodeGenerator {
         "DN_GenerateHashCode=Generate hashCode()...",
         "DN_GenerateEqualsHashCode=Generate equals() and hashCode()...",
     })
-    public List<CodeAction> getCodeActions(CompilationInfo info, 
CodeActionParams params) {
+    public List<CodeAction> getCodeActions(ResultIterator resultIterator, 
CodeActionParams params) throws Exception {
         List<String> only = params.getContext().getOnly();
         if (only == null || !only.contains(CodeActionKind.Source)) {
             return Collections.emptyList();
         }
+        CompilationController info = 
CompilationController.get(resultIterator.getParserResult());
+        if (info == null) {
+            return Collections.emptyList();
+        }
+        info.toPhase(JavaSource.Phase.RESOLVED);
         int offset = getOffset(info, params.getRange().getStart());
         TreePath tp = info.getTreeUtilities().pathFor(offset);
         tp = info.getTreeUtilities().getPathElementOfKind(Tree.Kind.CLASS, tp);
diff --git 
a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/GetterSetterGenerator.java
 
b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/GetterSetterGenerator.java
index 4b7df97..9841873 100644
--- 
a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/GetterSetterGenerator.java
+++ 
b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/GetterSetterGenerator.java
@@ -46,12 +46,14 @@ import org.eclipse.lsp4j.Range;
 import org.eclipse.lsp4j.TextEdit;
 import org.eclipse.lsp4j.WorkspaceEdit;
 import org.netbeans.api.java.source.CodeStyle;
+import org.netbeans.api.java.source.CompilationController;
 import org.netbeans.api.java.source.CompilationInfo;
 import org.netbeans.api.java.source.ElementUtilities;
 import org.netbeans.api.java.source.JavaSource;
 import org.netbeans.api.java.source.TreeUtilities;
 import org.netbeans.modules.java.editor.codegen.GeneratorUtils;
 import org.netbeans.modules.java.lsp.server.Utils;
+import org.netbeans.modules.parsing.api.ResultIterator;
 import org.openide.filesystems.FileObject;
 import org.openide.util.NbBundle;
 import org.openide.util.Pair;
@@ -61,8 +63,8 @@ import org.openide.util.lookup.ServiceProvider;
  *
  * @author lahvac
  */
-@ServiceProvider(service = CodeGenerator.class, position = 30)
-public final class GetterSetterGenerator extends CodeGenerator {
+@ServiceProvider(service = CodeActionsProvider.class, position = 30)
+public final class GetterSetterGenerator extends CodeActionsProvider {
 
     public static final String GENERATE_GETTERS =  "java.generate.getters";
     public static final String GENERATE_SETTERS =  "java.generate.setters";
@@ -83,7 +85,12 @@ public final class GetterSetterGenerator extends 
CodeGenerator {
         "DN_GenerateSetterFor=Generate Setter for \"{0}\"",
         "DN_GenerateGetterSetterFor=Generate Getter and Setter for \"{0}\"",
     })
-    public List<CodeAction> getCodeActions(CompilationInfo info, 
CodeActionParams params) {
+    public List<CodeAction> getCodeActions(ResultIterator resultIterator, 
CodeActionParams params) throws Exception {
+        CompilationController info = 
CompilationController.get(resultIterator.getParserResult());
+        if (info == null) {
+            return Collections.emptyList();
+        }
+        info.toPhase(JavaSource.Phase.RESOLVED);
         List<String> only = params.getContext().getOnly();
         boolean all = only != null && only.contains(CodeActionKind.Source);
         Pair<Set<VariableElement>, Set<VariableElement>> pair = 
findMissingGettersSetters(info, params.getRange(), all);
diff --git 
a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/ImplementOverrideMethodGenerator.java
 
b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/ImplementOverrideMethodGenerator.java
index 231287d..59d0c83 100644
--- 
a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/ImplementOverrideMethodGenerator.java
+++ 
b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/ImplementOverrideMethodGenerator.java
@@ -43,12 +43,13 @@ import org.eclipse.lsp4j.MessageParams;
 import org.eclipse.lsp4j.MessageType;
 import org.eclipse.lsp4j.TextEdit;
 import org.eclipse.lsp4j.WorkspaceEdit;
-import org.netbeans.api.java.source.CompilationInfo;
+import org.netbeans.api.java.source.CompilationController;
 import org.netbeans.api.java.source.ElementUtilities;
 import org.netbeans.api.java.source.JavaSource;
 import org.netbeans.api.java.source.TreeUtilities;
 import org.netbeans.modules.java.editor.codegen.GeneratorUtils;
 import org.netbeans.modules.java.lsp.server.Utils;
+import org.netbeans.modules.parsing.api.ResultIterator;
 import org.openide.filesystems.FileObject;
 import org.openide.util.NbBundle;
 import org.openide.util.lookup.ServiceProvider;
@@ -57,8 +58,8 @@ import org.openide.util.lookup.ServiceProvider;
  *
  * @author Dusan Balek
  */
-@ServiceProvider(service = CodeGenerator.class, position = 70)
-public final class ImplementOverrideMethodGenerator extends CodeGenerator {
+@ServiceProvider(service = CodeActionsProvider.class, position = 70)
+public final class ImplementOverrideMethodGenerator extends 
CodeActionsProvider {
 
     public static final String GENERATE_IMPLEMENT_METHOD =  
"java.generate.implementMethod";
     public static final String GENERATE_OVERRIDE_METHOD =  
"java.generate.overrideMethod";
@@ -75,11 +76,16 @@ public final class ImplementOverrideMethodGenerator extends 
CodeGenerator {
         "DN_GenerateOverrideMethod=Generate Override Method...",
         "DN_From=(from {0})",
     })
-    public List<CodeAction> getCodeActions(CompilationInfo info, 
CodeActionParams params) {
+    public List<CodeAction> getCodeActions(ResultIterator resultIterator, 
CodeActionParams params) throws Exception {
         List<String> only = params.getContext().getOnly();
         if (only == null || !only.contains(CodeActionKind.Source)) {
             return Collections.emptyList();
         }
+        CompilationController info = 
CompilationController.get(resultIterator.getParserResult());
+        if (info == null) {
+            return Collections.emptyList();
+        }
+        info.toPhase(JavaSource.Phase.RESOLVED);
         int offset = getOffset(info, params.getRange().getStart());
         TreePath tp = info.getTreeUtilities().pathFor(offset);
         tp = 
info.getTreeUtilities().getPathElementOfKind(TreeUtilities.CLASS_TREE_KINDS, 
tp);
diff --git 
a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/LoggerGenerator.java
 
b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/LoggerGenerator.java
index e0fcc30..824838d 100644
--- 
a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/LoggerGenerator.java
+++ 
b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/LoggerGenerator.java
@@ -44,11 +44,12 @@ import org.eclipse.lsp4j.MessageParams;
 import org.eclipse.lsp4j.MessageType;
 import org.eclipse.lsp4j.TextEdit;
 import org.eclipse.lsp4j.WorkspaceEdit;
-import org.netbeans.api.java.source.CompilationInfo;
+import org.netbeans.api.java.source.CompilationController;
 import org.netbeans.api.java.source.GeneratorUtilities;
 import org.netbeans.api.java.source.JavaSource;
 import org.netbeans.api.java.source.TreeUtilities;
 import org.netbeans.modules.java.lsp.server.Utils;
+import org.netbeans.modules.parsing.api.ResultIterator;
 import org.openide.filesystems.FileObject;
 import org.openide.util.BaseUtilities;
 import org.openide.util.NbBundle;
@@ -58,8 +59,8 @@ import org.openide.util.lookup.ServiceProvider;
  *
  * @author Dusan Balek
  */
-@ServiceProvider(service = CodeGenerator.class, position = 20)
-public final class LoggerGenerator extends CodeGenerator {
+@ServiceProvider(service = CodeActionsProvider.class, position = 20)
+public final class LoggerGenerator extends CodeActionsProvider {
 
     public static final String GENERATE_LOGGER =  "java.generate.logger";
 
@@ -73,11 +74,16 @@ public final class LoggerGenerator extends CodeGenerator {
     @NbBundle.Messages({
         "DN_GenerateLogger=Generate Logger...",
     })
-    public List<CodeAction> getCodeActions(CompilationInfo info, 
CodeActionParams params) {
+    public List<CodeAction> getCodeActions(ResultIterator resultIterator, 
CodeActionParams params) throws Exception {
         List<String> only = params.getContext().getOnly();
         if (only == null || !only.contains(CodeActionKind.Source)) {
             return Collections.emptyList();
         }
+        CompilationController info = 
CompilationController.get(resultIterator.getParserResult());
+        if (info == null) {
+            return Collections.emptyList();
+        }
+        info.toPhase(JavaSource.Phase.RESOLVED);
         int offset = getOffset(info, params.getRange().getStart());
         TreePath tp = info.getTreeUtilities().pathFor(offset);
         tp = 
info.getTreeUtilities().getPathElementOfKind(TreeUtilities.CLASS_TREE_KINDS, 
tp);
diff --git 
a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/MoveRefactoring.java
 
b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/MoveRefactoring.java
new file mode 100644
index 0000000..60e4f68
--- /dev/null
+++ 
b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/MoveRefactoring.java
@@ -0,0 +1,373 @@
+/*
+ * 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.java.lsp.server.protocol;
+
+import com.google.gson.Gson;
+import com.sun.source.tree.ClassTree;
+import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.util.SourcePositions;
+import com.sun.source.util.Trees;
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.function.Consumer;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.TypeElement;
+import org.eclipse.lsp4j.ApplyWorkspaceEditParams;
+import org.eclipse.lsp4j.CodeAction;
+import org.eclipse.lsp4j.CodeActionKind;
+import org.eclipse.lsp4j.CodeActionParams;
+import org.eclipse.lsp4j.DeleteFile;
+import org.eclipse.lsp4j.MessageParams;
+import org.eclipse.lsp4j.MessageType;
+import org.eclipse.lsp4j.Range;
+import org.eclipse.lsp4j.RenameFile;
+import org.eclipse.lsp4j.ResourceOperation;
+import org.eclipse.lsp4j.TextDocumentEdit;
+import org.eclipse.lsp4j.TextEdit;
+import org.eclipse.lsp4j.VersionedTextDocumentIdentifier;
+import org.eclipse.lsp4j.WorkspaceEdit;
+import org.eclipse.lsp4j.jsonrpc.messages.Either;
+import org.netbeans.api.java.classpath.ClassPath;
+import org.netbeans.api.java.project.JavaProjectConstants;
+import org.netbeans.api.java.source.ClassIndex;
+import org.netbeans.api.java.source.ClasspathInfo;
+import org.netbeans.api.java.source.CompilationController;
+import org.netbeans.api.java.source.CompilationInfo;
+import org.netbeans.api.java.source.ElementHandle;
+import org.netbeans.api.java.source.JavaSource;
+import org.netbeans.api.java.source.ModificationResult;
+import org.netbeans.api.java.source.TreePathHandle;
+import org.netbeans.api.project.FileOwnerQuery;
+import org.netbeans.api.project.Project;
+import org.netbeans.api.project.ProjectUtils;
+import org.netbeans.api.project.SourceGroup;
+import org.netbeans.modules.java.lsp.server.Utils;
+import org.netbeans.modules.parsing.api.ResultIterator;
+import org.netbeans.modules.refactoring.api.Problem;
+import org.netbeans.modules.refactoring.api.RefactoringSession;
+import org.netbeans.modules.refactoring.api.impl.APIAccessor;
+import org.netbeans.modules.refactoring.api.impl.SPIAccessor;
+import org.netbeans.modules.refactoring.java.api.JavaMoveMembersProperties;
+import org.netbeans.modules.refactoring.java.api.JavaRefactoringUtils;
+import org.netbeans.modules.refactoring.java.spi.hooks.JavaModificationResult;
+import org.netbeans.modules.refactoring.plugins.FileMovePlugin;
+import org.netbeans.modules.refactoring.spi.RefactoringCommit;
+import org.netbeans.modules.refactoring.spi.RefactoringElementImplementation;
+import org.netbeans.modules.refactoring.spi.Transaction;
+import org.netbeans.spi.java.classpath.support.ClassPathSupport;
+import org.openide.filesystems.FileObject;
+import org.openide.util.NbBundle;
+import org.openide.util.lookup.Lookups;
+import org.openide.util.lookup.ServiceProvider;
+
+/**
+ *
+ * @author Dusan Balek
+ */
+@ServiceProvider(service = CodeActionsProvider.class, position = 160)
+public class MoveRefactoring extends CodeActionsProvider {
+
+    private static final String MOVE_REFACTORING_KIND = "refactor.move";
+    private static final String MOVE_REFACTORING_COMMAND =  
"java.refactor.move";
+    private static final ClassPath EMPTY_PATH = 
ClassPathSupport.createClassPath(new URL[0]);
+
+    private final Set<String> commands = 
Collections.singleton(MOVE_REFACTORING_COMMAND);
+    private final Gson gson = new Gson();
+
+    @Override
+    @NbBundle.Messages({
+        "DN_Move= Move...",
+    })
+    public List<CodeAction> getCodeActions(ResultIterator resultIterator, 
CodeActionParams params) throws Exception {
+        List<String> only = params.getContext().getOnly();
+        if (only == null || !only.contains(CodeActionKind.Refactor)) {
+            return Collections.emptyList();
+        }
+        CompilationController info = 
CompilationController.get(resultIterator.getParserResult());
+        if (info == null || 
!JavaRefactoringUtils.isRefactorable(info.getFileObject())) {
+            return Collections.emptyList();
+        }
+        info.toPhase(JavaSource.Phase.ELEMENTS_RESOLVED);
+        int offset = getOffset(info, params.getRange().getStart());
+        String uri = Utils.toUri(info.getFileObject());
+        Element element = elementForOffset(info, offset);
+        if (element != null) {
+            QuickPickItem elementItem = new QuickPickItem(createLabel(info, 
element));
+            elementItem.setUserData(new ElementData(element));
+            return 
Collections.singletonList(createCodeAction(Bundle.DN_Move(), 
MOVE_REFACTORING_KIND, MOVE_REFACTORING_COMMAND, uri, elementItem));
+        } else {
+            return 
Collections.singletonList(createCodeAction(Bundle.DN_Move(), 
MOVE_REFACTORING_KIND, MOVE_REFACTORING_COMMAND, uri));
+        }
+    }
+
+    @Override
+    public Set<String> getCommands() {
+        return commands;
+    }
+
+    @Override
+    @NbBundle.Messages({
+        "DN_DefaultPackage=<default package>",
+        "DN_SelectTargetPackage=Select target package",
+        "DN_CreateNewClass=<create new class>",
+        "DN_SelectTargetClass=Select target class",
+    })
+    public CompletableFuture<Object> processCommand(NbCodeLanguageClient 
client, String command, List<Object> arguments) {
+        try {
+            if (arguments.size() > 0) {
+                String uri = gson.fromJson(gson.toJson(arguments.get(0)), 
String.class);
+                QuickPickItem elementItem = arguments.size() > 1 ? 
gson.fromJson(gson.toJson(arguments.get(1)), QuickPickItem.class) : null;
+                FileObject file = Utils.fromUri(uri);
+                Project project = FileOwnerQuery.getOwner(file);
+                HashSet<QuickPickItem> items = new HashSet<>();
+                if (project != null) {
+                    for(SourceGroup sourceGroup : 
ProjectUtils.getSources(project).getSourceGroups(JavaProjectConstants.SOURCES_TYPE_JAVA))
 {
+                        String name = sourceGroup.getDisplayName();
+                        FileObject rootFolder = sourceGroup.getRootFolder();
+                        if (elementItem == null) {
+                            items.add(new 
QuickPickItem(Bundle.DN_DefaultPackage(), name, null, false, 
Utils.toUri(rootFolder)));
+                        }
+                        for (String packageName : 
ClasspathInfo.create(rootFolder).getClassIndex().getPackageNames("", false, 
EnumSet.of(ClassIndex.SearchScope.SOURCE))) {
+                            if (elementItem == null) {
+                                String pkg = "";
+                                for (String part : packageName.split("\\.")) {
+                                    if (!part.isEmpty()) {
+                                        pkg += pkg.length() == 0 ? part : "." 
+ part;
+                                        items.add(new QuickPickItem(pkg, name, 
null, false, Utils.toUri(rootFolder.getFileObject(pkg.replace('.', '/')))));
+                                    }
+                                }
+                            } else {
+                                items.add(new QuickPickItem(packageName, name, 
null, false, Utils.toUri(rootFolder.getFileObject(packageName.replace('.', 
'/')))));
+                            }
+                        }
+                    }
+                }
+                ArrayList<QuickPickItem> packages = new ArrayList<>(items);
+                Collections.sort(packages, (item1, item2) -> {
+                    int i = 
item1.getDescription().compareTo(item2.getDescription());
+                    return i == 0 ? 
item1.getLabel().compareTo(item2.getLabel()) : i;
+                });
+                Consumer<List<QuickPickItem>> f = selectedPackage -> {
+                    if (selectedPackage != null && !selectedPackage.isEmpty()) 
{
+                        ClasspathInfo info = ClasspathInfo.create(file);
+                        TreePathHandle tph = elementItem != null ? 
TreePathHandle.from(gson.fromJson(gson.toJson(elementItem.getUserData()), 
ElementData.class).toHandle(), info) : null;
+                        List<QuickPickItem> classes = 
packageClasses(selectedPackage.get(0), tph == null || tph.getKind() == 
Tree.Kind.CLASS);
+                        if (classes.isEmpty()) {
+                            if (tph == null) {
+                                move(client, uri, selectedPackage.get(0), 
ClasspathInfo.create(file));
+                            } else {
+                                throw new 
IllegalArgumentException(String.format("No target class found in selected 
package"));
+                            }
+                        } else {
+                            client.showQuickPick(new 
ShowQuickPickParams(Bundle.DN_SelectTargetClass(), false, 
classes)).thenAccept(selectedClass -> {
+                                if (selectedClass != null && 
!selectedClass.isEmpty()) {
+                                    QuickPickItem selected = 
Bundle.DN_CreateNewClass().equals(selectedClass.get(0).getLabel()) ? 
selectedPackage.get(0) : selectedClass.get(0);
+                                    move(client, tph != null ? tph : uri, 
selected, info);
+                                }
+                            });
+                        }
+                    }
+                };
+                if (packages.size() == 1) {
+                    f.accept(packages);
+                } else {
+                    client.showQuickPick(new 
ShowQuickPickParams(Bundle.DN_SelectTargetPackage(), false, 
packages)).thenAccept(f);
+                }
+            } else {
+                throw new IllegalArgumentException(String.format("Illegal 
number of arguments received for command: %s", command));
+            }
+        } catch (Exception ex) {
+            client.logMessage(new MessageParams(MessageType.Error, 
ex.getLocalizedMessage()));
+        }
+        return CompletableFuture.completedFuture(true);
+    }
+
+    private void move(NbCodeLanguageClient client, Object source, 
QuickPickItem target, ClasspathInfo info) {
+        try {
+            org.netbeans.modules.refactoring.api.MoveRefactoring refactoring;
+            if (source instanceof String) {
+                FileObject file = Utils.fromUri((String) source);
+                refactoring = new 
org.netbeans.modules.refactoring.api.MoveRefactoring(Lookups.fixed(file));
+                
refactoring.getContext().add(JavaRefactoringUtils.getClasspathInfoFor(file));
+            } else {
+                TreePathHandle tph = (TreePathHandle) source;
+                refactoring = new 
org.netbeans.modules.refactoring.api.MoveRefactoring(Lookups.fixed(tph));
+                refactoring.getContext().add(tph.getKind() == Tree.Kind.CLASS 
? JavaRefactoringUtils.getClasspathInfoFor(tph.getFileObject()) : new 
JavaMoveMembersProperties(tph));
+            }
+            if (target.getDescription() != null) {
+                refactoring.setTarget(Lookups.singleton(new URL((String) 
target.getUserData())));
+            } else {
+                ElementHandle handle = 
gson.fromJson(gson.toJson(target.getUserData()), ElementData.class).toHandle();
+                
refactoring.setTarget(Lookups.singleton(TreePathHandle.from(handle, info)));
+            }
+            RefactoringSession session = RefactoringSession.create("Move");
+            Problem p = refactoring.checkParameters();
+            if (p != null && p.isFatal()) {
+                throw new IllegalStateException(p.getMessage());
+            }
+            p = refactoring.preCheck();
+            if (p != null && p.isFatal()) {
+                throw new IllegalStateException(p.getMessage());
+            }
+            p = refactoring.prepare(session);
+            if (p != null && p.isFatal()) {
+                throw new IllegalStateException(p.getMessage());
+            }
+            List<Either<TextDocumentEdit, ResourceOperation>> resultChanges = 
new ArrayList<>();
+            Map<String, String> renames = new HashMap<>();
+            List<RefactoringElementImplementation> fileChanges = 
APIAccessor.DEFAULT.getFileChanges(session);
+            for (RefactoringElementImplementation rei : fileChanges) {
+                if (rei instanceof FileMovePlugin.MoveFile) {
+                    String oldURI = Utils.toUri(rei.getParentFile());
+                    int slash = oldURI.lastIndexOf('/');
+                    URL url = refactoring.getTarget().lookup(URL.class);
+                    String newURI = url.toString() + oldURI.substring(slash + 
1);
+                    renames.put(oldURI, newURI);
+                    ResourceOperation op = new RenameFile(oldURI, newURI);
+                    resultChanges.add(Either.forRight(op));
+                } else if (rei instanceof 
org.netbeans.modules.refactoring.java.plugins.DeleteFile) {
+                    String oldURI = Utils.toUri(rei.getParentFile());
+                    ResourceOperation op = new DeleteFile(oldURI);
+                    resultChanges.add(Either.forRight(op));
+                } else {
+                    throw new IllegalStateException(rei.getClass().toString());
+                }
+            }
+            List<Transaction> transactions = 
APIAccessor.DEFAULT.getCommits(session);
+            List<ModificationResult> results = new ArrayList<>();
+            for (Transaction t : transactions) {
+                if (t instanceof RefactoringCommit) {
+                    RefactoringCommit c = (RefactoringCommit) t;
+                    for 
(org.netbeans.modules.refactoring.spi.ModificationResult refResult : 
SPIAccessor.DEFAULT.getTransactions(c)) {
+                        if (refResult instanceof JavaModificationResult) {
+                            results.add(((JavaModificationResult) 
refResult).delegate);
+                        } else {
+                            throw new 
IllegalStateException(refResult.getClass().toString());
+                        }
+                    }
+                } else {
+                    throw new IllegalStateException(t.getClass().toString());
+                }
+            }
+            for (ModificationResult mr : results) {
+                for (FileObject modified : mr.getModifiedFileObjects()) {
+                    String modifiedUri = Utils.toUri(modified);
+                    resultChanges.add(Either.forLeft(new TextDocumentEdit(new 
VersionedTextDocumentIdentifier(renames.getOrDefault(modifiedUri, modifiedUri), 
-1), fileModifications(mr, modified))));
+                }
+            }
+            session.finished();
+            client.applyEdit(new ApplyWorkspaceEditParams(new 
WorkspaceEdit(resultChanges)));
+        } catch (IOException | IllegalArgumentException ex) {
+            client.logMessage(new MessageParams(MessageType.Error, 
ex.getLocalizedMessage()));
+        }
+    }
+
+    private static List<TextEdit> fileModifications(ModificationResult 
changes, FileObject file) {
+        List<? extends ModificationResult.Difference> diffs = 
changes.getDifferences(file);
+        if (diffs == null) {
+            return Collections.emptyList();
+        }
+        List<TextEdit> edits = new ArrayList<>();
+        for (ModificationResult.Difference diff : diffs) {
+            String newText = diff.getNewText();
+            edits.add(new TextEdit(new Range(Utils.createPosition(file, 
diff.getStartPosition().getOffset()), Utils.createPosition(file, 
diff.getEndPosition().getOffset())), newText != null ? newText : ""));
+        }
+        return edits;
+    }
+
+    private static Element elementForOffset(CompilationInfo info, int offset) 
throws RuntimeException {
+        List<? extends TypeElement> topLevelElements = 
info.getTopLevelElements();
+        Trees trees = info.getTrees();
+        SourcePositions sourcePositions = trees.getSourcePositions();
+        CompilationUnitTree compilationUnit = info.getCompilationUnit();
+        for (TypeElement typeElement : topLevelElements) {
+            ClassTree topLevelClass = trees.getTree(typeElement);
+            long startPosition = 
sourcePositions.getStartPosition(compilationUnit, topLevelClass);
+            long endPosition = sourcePositions.getEndPosition(compilationUnit, 
topLevelClass);
+            if (offset > startPosition && offset < endPosition) {
+                for (Element element : typeElement.getEnclosedElements()) {
+                    Tree member = trees.getTree(element);
+                    long startMember = 
sourcePositions.getStartPosition(compilationUnit, member);
+                    long endMember = 
sourcePositions.getEndPosition(compilationUnit, member);
+                    if (offset > startMember && offset < endMember) {
+                        return element;
+                    }
+                }
+                return topLevelElements.size() > 1 ? typeElement : null;
+            }
+        }
+        return null;
+    }
+
+    private static List<QuickPickItem> packageClasses(QuickPickItem 
targetPackage, boolean proposeNew) {
+        try {
+            FileObject fo = Utils.fromUri((String) 
targetPackage.getUserData());
+            ClassPath sourcePath = ClassPath.getClassPath(fo, 
ClassPath.SOURCE);
+            final ClasspathInfo info = ClasspathInfo.create(EMPTY_PATH, 
EMPTY_PATH, sourcePath);
+            Set<ClassIndex.SearchScopeType> searchScopeType = new HashSet<>(1);
+            String packageName = 
Bundle.DN_DefaultPackage().equals(targetPackage.getLabel()) ? "" : 
targetPackage.getLabel();
+            final Set<String> packageSet = Collections.singleton(packageName);
+            searchScopeType.add(new ClassIndex.SearchScopeType() {
+                @Override
+                public Set<? extends String> getPackages() {
+                    return packageSet;
+                }
+
+                @Override
+                public boolean isSources() {
+                    return true;
+                }
+
+                @Override
+                public boolean isDependencies() {
+                    return false;
+                }
+            });
+            final Set<ElementHandle<TypeElement>> result = 
info.getClassIndex().getDeclaredTypes("", ClassIndex.NameKind.PREFIX, 
searchScopeType);
+            if (result != null && !result.isEmpty()) {
+                List<QuickPickItem> ret = new ArrayList<>(result.size() + 1);
+                if (proposeNew) {
+                    ret.add(new QuickPickItem(Bundle.DN_CreateNewClass()));
+                }
+                for (ElementHandle<TypeElement> elementHandle : result) {
+                    String qualifiedName = elementHandle.getQualifiedName();
+                    if (qualifiedName.startsWith(packageName)) {
+                        String shortName = 
qualifiedName.substring(packageName.length() + 1);
+                        int idx = shortName.indexOf('.');
+                        if (fo.getFileObject(idx < 0 ? shortName : 
shortName.substring(0, idx), "java") != null) {
+                            ret.add(new QuickPickItem(shortName, null, null, 
false, new ElementData(elementHandle)));
+                        }
+                    }
+                }
+                return ret;
+            }
+        } catch (Exception ex) {}
+        return Collections.emptyList();
+    }
+}
diff --git 
a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/Server.java
 
b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/Server.java
index 2221a83..652c860 100644
--- 
a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/Server.java
+++ 
b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/Server.java
@@ -613,7 +613,7 @@ public final class Server {
                 
completionOptions.setTriggerCharacters(Collections.singletonList("."));
                 capabilities.setCompletionProvider(completionOptions);
                 capabilities.setHoverProvider(true);
-                capabilities.setCodeActionProvider(new 
CodeActionOptions(Arrays.asList(CodeActionKind.QuickFix, 
CodeActionKind.Source)));
+                capabilities.setCodeActionProvider(new 
CodeActionOptions(Arrays.asList(CodeActionKind.QuickFix, CodeActionKind.Source, 
CodeActionKind.Refactor)));
                 capabilities.setDocumentSymbolProvider(true);
                 capabilities.setDefinitionProvider(true);
                 capabilities.setTypeDefinitionProvider(true);
@@ -635,8 +635,8 @@ public final class Server {
                         JAVA_PROJECT_CONFIGURATION_COMPLETION,
                         JAVA_SUPER_IMPLEMENTATION,
                         NATIVE_IMAGE_FIND_DEBUG_PROCESS_TO_ATTACH));
-                for (CodeGenerator codeGenerator : 
Lookup.getDefault().lookupAll(CodeGenerator.class)) {
-                    commands.addAll(codeGenerator.getCommands());
+                for (CodeActionsProvider codeActionsProvider : 
Lookup.getDefault().lookupAll(CodeActionsProvider.class)) {
+                    commands.addAll(codeActionsProvider.getCommands());
                 }
                 capabilities.setExecuteCommandProvider(new 
ExecuteCommandOptions(commands));
                 capabilities.setWorkspaceSymbolProvider(true);
@@ -870,7 +870,7 @@ public final class Server {
      * @param caps 
      */
     private static void hackConfigureGroovySupport(NbCodeClientCapabilities 
caps) {
-        boolean b = caps.wantsGroovySupport();
+        boolean b = caps != null && caps.wantsGroovySupport();
         try {
             Class clazz = 
Lookup.getDefault().lookup(ClassLoader.class).loadClass("org.netbeans.modules.groovy.editor.api.GroovyIndexer");
             Method m = clazz.getDeclaredMethod("setIndexingEnabled", 
Boolean.TYPE);
diff --git 
a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/TextDocumentServiceImpl.java
 
b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/TextDocumentServiceImpl.java
index 3e91b48..d69bc85 100644
--- 
a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/TextDocumentServiceImpl.java
+++ 
b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/TextDocumentServiceImpl.java
@@ -833,62 +833,68 @@ public class TextDocumentServiceImpl implements 
TextDocumentService, LanguageCli
         }
 
         final CompletableFuture<List<Either<Command, CodeAction>>> 
resultFuture = new CompletableFuture<>();
-        JavaSource js = JavaSource.forDocument(doc);
-        if (js == null) {
-            resultFuture.complete(result);
-            return resultFuture;
-        }
+        Source source = Source.create(doc);
         BACKGROUND_TASKS.post(() -> {
             try {
-                js.runUserActionTask(cc -> {
-                    cc.toPhase(JavaSource.Phase.RESOLVED);
-                    //code generators:
-                    for (CodeGenerator codeGenerator : 
Lookup.getDefault().lookupAll(CodeGenerator.class)) {
-                        for (CodeAction codeAction : 
codeGenerator.getCodeActions(cc, params)) {
-                            result.add(Either.forRight(codeAction));
+                ParserManager.parse(Collections.singleton(source), new 
UserTask() {
+                    @Override
+                    public void run(ResultIterator resultIterator) throws 
Exception {
+                        //code generators:
+                        for (CodeActionsProvider codeGenerator : 
Lookup.getDefault().lookupAll(CodeActionsProvider.class)) {
+                            try {
+                                for (CodeAction codeAction : 
codeGenerator.getCodeActions(resultIterator, params)) {
+                                    result.add(Either.forRight(codeAction));
+                                }
+                            } catch (Exception ex) {
+                                client.logMessage(new 
MessageParams(MessageType.Error, ex.getMessage()));
+                            }
                         }
-                    }
-                    //introduce hints
-                    if (!range.getStart().equals(range.getEnd())) {
-                        for (ErrorDescription err : 
IntroduceHint.computeError(cc, startOffset, endOffset, new 
EnumMap<IntroduceKind, Fix>(IntroduceKind.class), new EnumMap<IntroduceKind, 
String>(IntroduceKind.class), new AtomicBoolean())) {
-                            for (Fix fix : err.getFixes().getFixes()) {
-                                if (fix instanceof IntroduceFixBase) {
-                                    try {
-                                        ModificationResult changes = 
((IntroduceFixBase) fix).getModificationResult();
-                                        if (changes != null) {
-                                            List<Either<TextDocumentEdit, 
ResourceOperation>> documentChanges = new ArrayList<>();
-                                            Set<? extends FileObject> fos = 
changes.getModifiedFileObjects();
-                                            if (fos.size() == 1) {
-                                                FileObject fileObject = 
fos.iterator().next();
-                                                List<? extends 
ModificationResult.Difference> diffs = changes.getDifferences(fileObject);
-                                                if (diffs != null) {
-                                                    List<TextEdit> edits = new 
ArrayList<>();
-                                                    for 
(ModificationResult.Difference diff : diffs) {
-                                                        String newText = 
diff.getNewText();
-                                                        edits.add(new 
TextEdit(new Range(Utils.createPosition(fileObject, 
diff.getStartPosition().getOffset()),
-                                                                
Utils.createPosition(fileObject, diff.getEndPosition().getOffset())),
-                                                                newText != 
null ? newText : ""));
+                        //introduce hints:
+                        CompilationController cc = 
CompilationController.get(resultIterator.getParserResult());
+                        if (cc != null) {
+                            cc.toPhase(JavaSource.Phase.RESOLVED);
+                            if (!range.getStart().equals(range.getEnd())) {
+                                for (ErrorDescription err : 
IntroduceHint.computeError(cc, startOffset, endOffset, new 
EnumMap<IntroduceKind, Fix>(IntroduceKind.class), new EnumMap<IntroduceKind, 
String>(IntroduceKind.class), new AtomicBoolean())) {
+                                    for (Fix fix : err.getFixes().getFixes()) {
+                                        if (fix instanceof IntroduceFixBase) {
+                                            try {
+                                                ModificationResult changes = 
((IntroduceFixBase) fix).getModificationResult();
+                                                if (changes != null) {
+                                                    
List<Either<TextDocumentEdit, ResourceOperation>> documentChanges = new 
ArrayList<>();
+                                                    Set<? extends FileObject> 
fos = changes.getModifiedFileObjects();
+                                                    if (fos.size() == 1) {
+                                                        FileObject fileObject 
= fos.iterator().next();
+                                                        List<? extends 
ModificationResult.Difference> diffs = changes.getDifferences(fileObject);
+                                                        if (diffs != null) {
+                                                            List<TextEdit> 
edits = new ArrayList<>();
+                                                            for 
(ModificationResult.Difference diff : diffs) {
+                                                                String newText 
= diff.getNewText();
+                                                                edits.add(new 
TextEdit(new Range(Utils.createPosition(fileObject, 
diff.getStartPosition().getOffset()),
+                                                                        
Utils.createPosition(fileObject, diff.getEndPosition().getOffset())),
+                                                                        
newText != null ? newText : ""));
+                                                            }
+                                                            
documentChanges.add(Either.forLeft(new TextDocumentEdit(new 
VersionedTextDocumentIdentifier(Utils.toUri(fileObject), -1), edits)));
+                                                        }
+                                                        CodeAction codeAction 
= new CodeAction(fix.getText());
+                                                        
codeAction.setKind(CodeActionKind.RefactorExtract);
+                                                        codeAction.setEdit(new 
WorkspaceEdit(documentChanges));
+                                                        int renameOffset = 
((IntroduceFixBase) fix).getNameOffset(changes);
+                                                        if (renameOffset >= 0) 
{
+                                                            
codeAction.setCommand(new Command("Rename", "java.rename.element.at", 
Collections.singletonList(renameOffset)));
+                                                        }
+                                                        
result.add(Either.forRight(codeAction));
                                                     }
-                                                    
documentChanges.add(Either.forLeft(new TextDocumentEdit(new 
VersionedTextDocumentIdentifier(Utils.toUri(fileObject), -1), edits)));
                                                 }
-                                                CodeAction codeAction = new 
CodeAction(fix.getText());
-                                                
codeAction.setKind(CodeActionKind.RefactorExtract);
-                                                codeAction.setEdit(new 
WorkspaceEdit(documentChanges));
-                                                int renameOffset = 
((IntroduceFixBase) fix).getNameOffset(changes);
-                                                if (renameOffset >= 0) {
-                                                    codeAction.setCommand(new 
Command("Rename", "java.rename.element.at", 
Collections.singletonList(renameOffset)));
-                                                }
-                                                
result.add(Either.forRight(codeAction));
+                                            } catch 
(GeneratorUtils.DuplicateMemberException dme) {
                                             }
                                         }
-                                    } catch 
(GeneratorUtils.DuplicateMemberException dme) {
                                     }
                                 }
                             }
                         }
                     }
-                }, true);
-            } catch (IOException ex) {
+                });
+            } catch (ParseException ex) {
                 //TODO: include stack trace:
                 client.logMessage(new MessageParams(MessageType.Error, 
ex.getMessage()));
             } finally {
@@ -1166,7 +1172,7 @@ public class TextDocumentServiceImpl implements 
TextDocumentService, LanguageCli
                 }
                 for (ModificationResult mr : results) {
                     for (FileObject modified : mr.getModifiedFileObjects()) {
-                        resultChanges.add(Either.forLeft(new 
TextDocumentEdit(new 
VersionedTextDocumentIdentifier(params.getTextDocument().getUri(), /*XXX*/-1), 
fileModifications(mr, modified, null))));
+                        resultChanges.add(Either.forLeft(new 
TextDocumentEdit(new VersionedTextDocumentIdentifier(Utils.toUri(modified), 
/*XXX*/-1), fileModifications(mr, modified, null))));
                     }
                 }
                 List<RefactoringElementImplementation> fileChanges = 
APIAccessor.DEFAULT.getFileChanges(session);
diff --git 
a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/ToStringGenerator.java
 
b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/ToStringGenerator.java
index 846bd3f..70dc949 100644
--- 
a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/ToStringGenerator.java
+++ 
b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/ToStringGenerator.java
@@ -43,11 +43,12 @@ import org.eclipse.lsp4j.MessageParams;
 import org.eclipse.lsp4j.MessageType;
 import org.eclipse.lsp4j.TextEdit;
 import org.eclipse.lsp4j.WorkspaceEdit;
-import org.netbeans.api.java.source.CompilationInfo;
+import org.netbeans.api.java.source.CompilationController;
 import org.netbeans.api.java.source.GeneratorUtilities;
 import org.netbeans.api.java.source.JavaSource;
 import org.netbeans.api.java.source.TreeUtilities;
 import org.netbeans.modules.java.lsp.server.Utils;
+import org.netbeans.modules.parsing.api.ResultIterator;
 import org.openide.filesystems.FileObject;
 import org.openide.util.NbBundle;
 import org.openide.util.lookup.ServiceProvider;
@@ -56,8 +57,8 @@ import org.openide.util.lookup.ServiceProvider;
  *
  * @author Dusan Balek
  */
-@ServiceProvider(service = CodeGenerator.class, position = 50)
-public final class ToStringGenerator extends CodeGenerator {
+@ServiceProvider(service = CodeActionsProvider.class, position = 50)
+public final class ToStringGenerator extends CodeActionsProvider {
 
     public static final String GENERATE_TO_STRING =  "java.generate.toString";
 
@@ -71,11 +72,16 @@ public final class ToStringGenerator extends CodeGenerator {
     @NbBundle.Messages({
         "DN_GenerateToString=Generate toString()...",
     })
-    public List<CodeAction> getCodeActions(CompilationInfo info, 
CodeActionParams params) {
+    public List<CodeAction> getCodeActions(ResultIterator resultIterator, 
CodeActionParams params) throws Exception {
         List<String> only = params.getContext().getOnly();
         if (only == null || !only.contains(CodeActionKind.Source)) {
             return Collections.emptyList();
         }
+        CompilationController info = 
CompilationController.get(resultIterator.getParserResult());
+        if (info == null) {
+            return Collections.emptyList();
+        }
+        info.toPhase(JavaSource.Phase.RESOLVED);
         int offset = getOffset(info, params.getRange().getStart());
         TreePath tp = info.getTreeUtilities().pathFor(offset);
         tp = 
info.getTreeUtilities().getPathElementOfKind(TreeUtilities.CLASS_TREE_KINDS, 
tp);
diff --git 
a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/WorkspaceServiceImpl.java
 
b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/WorkspaceServiceImpl.java
index c018c71..43613d6 100644
--- 
a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/WorkspaceServiceImpl.java
+++ 
b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/WorkspaceServiceImpl.java
@@ -315,9 +315,9 @@ public final class WorkspaceServiceImpl implements 
WorkspaceService, LanguageCli
                 return (CompletableFuture<Object>) (CompletableFuture<?>) 
joinedFuture;
             }
             default:
-                for (CodeGenerator codeGenerator : 
Lookup.getDefault().lookupAll(CodeGenerator.class)) {
-                    if (codeGenerator.getCommands().contains(command)) {
-                        return codeGenerator.processCommand(client, command, 
params.getArguments());
+                for (CodeActionsProvider codeActionsProvider : 
Lookup.getDefault().lookupAll(CodeActionsProvider.class)) {
+                    if (codeActionsProvider.getCommands().contains(command)) {
+                        return codeActionsProvider.processCommand(client, 
command, params.getArguments());
                     }
                 }
         }
diff --git 
a/java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/protocol/ServerTest.java
 
b/java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/protocol/ServerTest.java
index 9f4fb43..c19c630 100644
--- 
a/java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/protocol/ServerTest.java
+++ 
b/java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/protocol/ServerTest.java
@@ -20,6 +20,7 @@ package org.netbeans.modules.java.lsp.server.protocol;
 
 import com.google.gson.Gson;
 import com.google.gson.JsonParser;
+import java.beans.PropertyChangeListener;
 import java.io.File;
 import java.io.FileWriter;
 import java.io.IOException;
@@ -53,6 +54,7 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.function.Consumer;
 import java.util.stream.Collectors;
+import javax.swing.Icon;
 import javax.swing.event.ChangeListener;
 import javax.swing.text.Document;
 import javax.swing.text.StyledDocument;
@@ -102,6 +104,7 @@ import org.eclipse.lsp4j.ReferenceParams;
 import org.eclipse.lsp4j.RenameFile;
 import org.eclipse.lsp4j.RenameParams;
 import org.eclipse.lsp4j.ResourceOperation;
+import org.eclipse.lsp4j.ResourceOperationKind;
 import org.eclipse.lsp4j.ShowMessageRequestParams;
 import org.eclipse.lsp4j.SymbolInformation;
 import org.eclipse.lsp4j.TextDocumentContentChangeEvent;
@@ -127,10 +130,15 @@ import org.eclipse.lsp4j.services.LanguageClient;
 import org.eclipse.lsp4j.services.LanguageServer;
 import org.netbeans.api.java.classpath.ClassPath;
 import org.netbeans.api.java.classpath.GlobalPathRegistry;
+import org.netbeans.api.java.project.JavaProjectConstants;
 import org.netbeans.api.java.queries.AnnotationProcessingQuery.Result;
 import org.netbeans.api.java.queries.AnnotationProcessingQuery.Trigger;
 import org.netbeans.api.java.source.JavaSource;
+import org.netbeans.api.project.FileOwnerQuery;
 import org.netbeans.api.project.Project;
+import org.netbeans.api.project.ProjectUtils;
+import org.netbeans.api.project.SourceGroup;
+import org.netbeans.api.project.Sources;
 import org.netbeans.api.project.ui.OpenProjects;
 import org.netbeans.api.sendopts.CommandLine;
 import org.netbeans.junit.NbTestCase;
@@ -138,6 +146,7 @@ import 
org.netbeans.modules.java.hints.infrastructure.JavaErrorProvider;
 import org.netbeans.modules.java.source.BootClassPathUtil;
 import org.netbeans.modules.parsing.impl.indexing.implspi.CacheFolderProvider;
 import org.netbeans.spi.java.classpath.ClassPathProvider;
+import org.netbeans.spi.java.classpath.PathResourceImplementation;
 import org.netbeans.spi.java.classpath.support.ClassPathSupport;
 import org.netbeans.spi.java.queries.AnnotationProcessingQueryImplementation;
 import org.netbeans.spi.lsp.ErrorProvider;
@@ -2588,7 +2597,7 @@ public class ServerTest extends NbTestCase {
         assertEquals(new Range(new Position(4, 0),
                                new Position(4, 0)),
                      fileChanges.get(2).getRange());
-        assertEquals("    private static PrintStream OUT = System.out;\n",
+        assertEquals("    private static final PrintStream OUT = 
System.out;\n",
                      fileChanges.get(2).getNewText());
         Command command = introduceConstant.get().getCommand();
         assertNotNull(command);
@@ -2596,7 +2605,7 @@ public class ServerTest extends NbTestCase {
         List<Object> arguments = command.getArguments();
         assertNotNull(arguments);
         assertEquals(1, arguments.size());
-        assertEquals("168", arguments.get(0).toString());
+        assertEquals("174", arguments.get(0).toString());
     }
 
     public void testCodeActionIntroduceField() throws Exception {
@@ -3864,14 +3873,14 @@ public class ServerTest extends NbTestCase {
                          WorkspaceEdit edit = cf.get();
                          assertTrue(edit.getChanges().isEmpty());
                          Set<String> actual = 
edit.getDocumentChanges().stream().map(this::toString).collect(Collectors.toSet());
-                         Set<String> expected = new 
HashSet<>(Arrays.asList("Test2.java:[3:25-3:28=>nue]", 
"Test2.java:[1:8-1:11=>nue]"));
+                         Set<String> expected = new 
HashSet<>(Arrays.asList("Test2.java:[3:25-3:28=>nue]", 
"Test.java:[1:8-1:11=>nue]"));
                          assertEquals(expected, actual);
                      },
                      cf -> {
                          WorkspaceEdit edit = cf.get();
                          assertTrue(edit.getChanges().isEmpty());
                          Set<String> actual = 
edit.getDocumentChanges().stream().map(this::toString).collect(Collectors.toSet());
-                         Set<String> expected = new 
HashSet<>(Arrays.asList("Test.java:[0:27-0:31=>TestNew, 1:4-1:8=>TestNew, 
2:11-2:15=>TestNew]", "Test.java:[0:13-0:17=>TestNew]", 
"Test.java=>TestNew.java"));
+                         Set<String> expected = new 
HashSet<>(Arrays.asList("Test2.java:[0:27-0:31=>TestNew, 1:4-1:8=>TestNew, 
2:11-2:15=>TestNew]", "Test.java:[0:13-0:17=>TestNew]", 
"Test.java=>TestNew.java"));
                          assertEquals(expected, actual);
                      });
     }
@@ -3888,14 +3897,14 @@ public class ServerTest extends NbTestCase {
                          WorkspaceEdit edit = cf.get();
                          assertTrue(edit.getChanges().isEmpty());
                          Set<String> actual = 
edit.getDocumentChanges().stream().map(this::toString).collect(Collectors.toSet());
-                         Set<String> expected = new 
HashSet<>(Arrays.asList("Test2.java:[3:25-3:28=>nue]", 
"Test2.java:[1:8-1:11=>nue]"));
+                         Set<String> expected = new 
HashSet<>(Arrays.asList("Test2.java:[3:25-3:28=>nue]", 
"Test.java:[1:8-1:11=>nue]"));
                          assertEquals(expected, actual);
                      },
                      cf -> {
                          WorkspaceEdit edit = cf.get();
                          assertTrue(edit.getChanges().isEmpty());
                          Set<String> actual = 
edit.getDocumentChanges().stream().map(this::toString).collect(Collectors.toSet());
-                         Set<String> expected = new 
HashSet<>(Arrays.asList("Test.java:[0:27-0:31=>TestNew, 1:4-1:8=>TestNew, 
2:11-2:15=>TestNew]", "Test.java:[0:13-0:17=>TestNew]", 
"Test.java=>TestNew.java"));
+                         Set<String> expected = new 
HashSet<>(Arrays.asList("Test2.java:[0:27-0:31=>TestNew, 1:4-1:8=>TestNew, 
2:11-2:15=>TestNew]", "Test.java:[0:13-0:17=>TestNew]", 
"Test.java=>TestNew.java"));
                          assertEquals(expected, actual);
                      });
     }
@@ -3913,12 +3922,13 @@ public class ServerTest extends NbTestCase {
             w.write(code);
         }
         File src2 = new File(getWorkDir(), "Test2.java");
+        String code2 = "public class Test2 extends Test {\n" +
+                       "    Test t;\n" +
+                       "    void m(Test p) {};\n" +
+                       "    int get() { return t.val; };\n" +
+                       "}\n";
         try (Writer w = new FileWriter(src2)) {
-            w.write("public class Test2 extends Test {\n" +
-                    "    Test t;\n" +
-                    "    void m(Test p) {};\n" +
-                    "    int get() { return t.val; };\n" +
-                    "}\n");
+            w.write(code2);
         }
         List<Diagnostic>[] diags = new List[1];
         CountDownLatch indexingComplete = new CountDownLatch(1);
@@ -3962,8 +3972,7 @@ public class ServerTest extends NbTestCase {
         settings.accept(initParams);
         InitializeResult result = server.initialize(initParams).get();
         indexingComplete.await();
-        server.getTextDocumentService().didOpen(new 
DidOpenTextDocumentParams(new TextDocumentItem(toURI(src), "java", 0, code)));
-
+        server.getTextDocumentService().didOpen(new 
DidOpenTextDocumentParams(new TextDocumentItem(toURI(src2), "java", 0, code2)));
         {
             RenameParams params = new RenameParams(new 
TextDocumentIdentifier(src2.toURI().toString()),
                                                    new Position(3, 27),
@@ -3971,7 +3980,7 @@ public class ServerTest extends NbTestCase {
 
             
validateFieldRename.validate(server.getTextDocumentService().rename(params));
         }
-
+        server.getTextDocumentService().didOpen(new 
DidOpenTextDocumentParams(new TextDocumentItem(toURI(src), "java", 0, code)));
         {
             RenameParams params = new RenameParams(new 
TextDocumentIdentifier(src.toURI().toString()),
                                                    new Position(0, 15),
@@ -3979,7 +3988,325 @@ public class ServerTest extends NbTestCase {
 
             
validateClassRename.validate(server.getTextDocumentService().rename(params));
         }
+    }
+
+    public void testMoveClass() throws Exception {
+        File src = new File(getWorkDir(), "a/Test.java");
+        src.getParentFile().mkdirs();
+        try (Writer w = new FileWriter(new 
File(src.getParentFile().getParentFile(), ".test-project"))) {}
+        String code = "package a;\n" +
+                      "\n" +
+                      "public class Test {\n" +
+                      "    void m() {}\n" +
+                      "}\n";
+        try (Writer w = new FileWriter(src)) {
+            w.write(code);
+        }
+        File src2 = new File(getWorkDir(), "b/Test2.java");
+        src2.getParentFile().mkdirs();
+        try (Writer w = new FileWriter(src2)) {
+            w.write("package b;\n" +
+                    "\n" +
+                    "import a.Test;\n" +
+                    "\n" +
+                    "public class Test2 {\n" +
+                    "    private Test t;\n" +
+                    "}\n");
+        }
+        List<Diagnostic>[] diags = new List[1];
+        CountDownLatch indexingComplete = new CountDownLatch(1);
+        WorkspaceEdit[] edit = new WorkspaceEdit[1];
+        Launcher<LanguageServer> serverLauncher = 
LSPLauncher.createClientLauncher(new NbCodeLanguageClient() {
+            @Override
+            public void telemetryEvent(Object arg0) {
+                throw new UnsupportedOperationException("Not supported yet.");
+            }
+
+            @Override
+            public void publishDiagnostics(PublishDiagnosticsParams params) {
+                synchronized (diags) {
+                    diags[0] = params.getDiagnostics();
+                    diags.notifyAll();
+                }
+            }
 
+            @Override
+            public void showMessage(MessageParams params) {
+                if (Server.INDEXING_COMPLETED.equals(params.getMessage())) {
+                    indexingComplete.countDown();
+                } else {
+                    throw new UnsupportedOperationException("Unexpected 
message.");
+                }
+            }
+
+            @Override
+            public CompletableFuture<MessageActionItem> 
showMessageRequest(ShowMessageRequestParams arg0) {
+                throw new UnsupportedOperationException("Not supported yet.");
+            }
+
+            @Override
+            public void logMessage(MessageParams arg0) {
+                throw new UnsupportedOperationException("Not supported yet.");
+            }
+
+            @Override
+            public CompletableFuture<ApplyWorkspaceEditResponse> 
applyEdit(ApplyWorkspaceEditParams params) {
+                edit[0] = params.getEdit();
+                return CompletableFuture.completedFuture(new 
ApplyWorkspaceEditResponse(false));
+            }
+
+            @Override
+            public CompletableFuture<String> 
createTextEditorDecoration(DecorationRenderOptions params) {
+                throw new UnsupportedOperationException("Not supported yet.");
+            }
+
+            @Override
+            public void disposeTextEditorDecoration(String params) {
+                throw new UnsupportedOperationException("Not supported yet.");
+            }
+
+            @Override
+            public NbCodeClientCapabilities getNbCodeCapabilities() {
+                throw new UnsupportedOperationException("Not supported yet.");
+            }
+
+            @Override
+            public void notifyTestProgress(TestProgressParams params) {
+                throw new UnsupportedOperationException("Not supported yet.");
+            }
+
+            @Override
+            public void setTextEditorDecoration(SetTextEditorDecorationParams 
params) {
+                throw new UnsupportedOperationException("Not supported yet.");
+            }
+
+            @Override
+            public CompletableFuture<String> showInputBox(ShowInputBoxParams 
params) {
+                throw new UnsupportedOperationException("Not supported yet.");
+            }
+
+            @Override
+            public CompletableFuture<List<QuickPickItem>> 
showQuickPick(ShowQuickPickParams params) {
+                List<QuickPickItem> items = params.getItems();
+                return 
CompletableFuture.completedFuture(Bundle.DN_SelectTargetPackage().equals(params.getPlaceHolder())
 ? items.subList(2, 3) : items.subList(0, 1));
+            }
+
+            @Override
+            public void showStatusBarMessage(ShowStatusMessageParams params) {
+                throw new UnsupportedOperationException("Not supported yet.");
+            }
+        }, client.getInputStream(), client.getOutputStream());
+        serverLauncher.startListening();
+        LanguageServer server = serverLauncher.getRemoteProxy();
+        InitializeParams initParams = new InitializeParams();
+        initParams.setRootUri(getWorkDir().toURI().toString());
+        InitializeResult result = server.initialize(initParams).get();
+        indexingComplete.await();
+        server.getTextDocumentService().didOpen(new 
DidOpenTextDocumentParams(new TextDocumentItem(toURI(src), "java", 0, code)));
+        VersionedTextDocumentIdentifier id = new 
VersionedTextDocumentIdentifier(src.toURI().toString(), 1);
+        List<Either<Command, CodeAction>> codeActions = 
server.getTextDocumentService().codeAction(new CodeActionParams(id, new 
Range(new Position(2, 17), new Position(2, 17)), new 
CodeActionContext(Arrays.asList(), 
Arrays.asList(CodeActionKind.Refactor)))).get();
+        Optional<CodeAction> move =
+                codeActions.stream()
+                           .filter(Either::isRight)
+                           .map(Either::getRight)
+                           .filter(a -> Bundle.DN_Move().equals(a.getTitle()))
+                           .findAny();
+        assertTrue(move.isPresent());
+        server.getWorkspaceService().executeCommand(new 
ExecuteCommandParams(move.get().getCommand().getCommand(), 
move.get().getCommand().getArguments())).get();
+        int cnt = 0;
+        while(edit[0] == null && cnt++ < 10) {
+            Thread.sleep(1000);
+        }
+        List<Either<TextDocumentEdit, ResourceOperation>> documentChanges = 
edit[0].getDocumentChanges();
+        assertEquals(3, documentChanges.size());
+        Either<TextDocumentEdit, ResourceOperation> change = 
documentChanges.get(0);
+        assertTrue(change.isRight());
+        ResourceOperation ro = change.getRight();
+        assertEquals(ResourceOperationKind.Rename, ro.getKind());
+        assertTrue(((RenameFile) ro).getOldUri().endsWith("a/Test.java"));
+        assertTrue(((RenameFile) ro).getNewUri().endsWith("b/Test.java"));
+        for (int i = 1; i <= 2; i++) {
+            change = documentChanges.get(i);
+            assertTrue(change.isLeft());
+            TextDocumentEdit tde = change.getLeft();
+            if (tde.getTextDocument().getUri().endsWith("b/Test.java")) {
+                List<TextEdit> fileChanges = tde.getEdits();
+                assertNotNull(fileChanges);
+                assertEquals(1, fileChanges.size());
+                assertEquals(new Range(new Position(0, 8),
+                                       new Position(0, 9)),
+                             fileChanges.get(0).getRange());
+                assertEquals("b", fileChanges.get(0).getNewText());
+            } else if 
(tde.getTextDocument().getUri().endsWith("b/Test2.java")) {
+                List<TextEdit> fileChanges = tde.getEdits();
+                assertNotNull(fileChanges);
+                assertEquals(1, fileChanges.size());
+                assertEquals(new Range(new Position(1, 0),
+                                       new Position(3, 0)),
+                             fileChanges.get(0).getRange());
+                assertEquals("", fileChanges.get(0).getNewText());
+            } else {
+                fail("Unknown file modified");
+            }
+        }
+    }
+
+    public void testMoveMethod() throws Exception {
+        File src = new File(getWorkDir(), "a/Test.java");
+        src.getParentFile().mkdirs();
+        try (Writer w = new FileWriter(new 
File(src.getParentFile().getParentFile(), ".test-project"))) {}
+        String code = "package a;\n" +
+                      "\n" +
+                      "import b.Test2;\n" +
+                      "\n" +
+                      "public class Test {\n" +
+                      "    void m(Test t, Test2 t2) {}\n" +
+                      "}\n";
+        try (Writer w = new FileWriter(src)) {
+            w.write(code);
+        }
+        File src2 = new File(getWorkDir(), "b/Test2.java");
+        src2.getParentFile().mkdirs();
+        try (Writer w = new FileWriter(src2)) {
+            w.write("package b;\n" +
+                    "\n" +
+                    "public class Test2 {\n" +
+                    "}\n");
+        }
+        List<Diagnostic>[] diags = new List[1];
+        CountDownLatch indexingComplete = new CountDownLatch(1);
+        WorkspaceEdit[] edit = new WorkspaceEdit[1];
+        Launcher<LanguageServer> serverLauncher = 
LSPLauncher.createClientLauncher(new NbCodeLanguageClient() {
+            @Override
+            public void telemetryEvent(Object arg0) {
+                throw new UnsupportedOperationException("Not supported yet.");
+            }
+
+            @Override
+            public void publishDiagnostics(PublishDiagnosticsParams params) {
+                synchronized (diags) {
+                    diags[0] = params.getDiagnostics();
+                    diags.notifyAll();
+                }
+            }
+
+            @Override
+            public void showMessage(MessageParams params) {
+                if (Server.INDEXING_COMPLETED.equals(params.getMessage())) {
+                    indexingComplete.countDown();
+                } else {
+                    throw new UnsupportedOperationException("Unexpected 
message.");
+                }
+            }
+
+            @Override
+            public CompletableFuture<MessageActionItem> 
showMessageRequest(ShowMessageRequestParams arg0) {
+                throw new UnsupportedOperationException("Not supported yet.");
+            }
+
+            @Override
+            public void logMessage(MessageParams arg0) {
+                throw new UnsupportedOperationException("Not supported yet.");
+            }
+
+            @Override
+            public CompletableFuture<ApplyWorkspaceEditResponse> 
applyEdit(ApplyWorkspaceEditParams params) {
+                edit[0] = params.getEdit();
+                return CompletableFuture.completedFuture(new 
ApplyWorkspaceEditResponse(false));
+            }
+
+            @Override
+            public CompletableFuture<String> 
createTextEditorDecoration(DecorationRenderOptions params) {
+                throw new UnsupportedOperationException("Not supported yet.");
+            }
+
+            @Override
+            public void disposeTextEditorDecoration(String params) {
+                throw new UnsupportedOperationException("Not supported yet.");
+            }
+
+            @Override
+            public NbCodeClientCapabilities getNbCodeCapabilities() {
+                throw new UnsupportedOperationException("Not supported yet.");
+            }
+
+            @Override
+            public void notifyTestProgress(TestProgressParams params) {
+                throw new UnsupportedOperationException("Not supported yet.");
+            }
+
+            @Override
+            public void setTextEditorDecoration(SetTextEditorDecorationParams 
params) {
+                throw new UnsupportedOperationException("Not supported yet.");
+            }
+
+            @Override
+            public CompletableFuture<String> showInputBox(ShowInputBoxParams 
params) {
+                throw new UnsupportedOperationException("Not supported yet.");
+            }
+
+            @Override
+            public CompletableFuture<List<QuickPickItem>> 
showQuickPick(ShowQuickPickParams params) {
+                List<QuickPickItem> items = params.getItems();
+                return 
CompletableFuture.completedFuture(Bundle.DN_SelectTargetPackage().equals(params.getPlaceHolder())
 ? items.subList(1, 2) : items.subList(0, 1));
+            }
+
+            @Override
+            public void showStatusBarMessage(ShowStatusMessageParams params) {
+                throw new UnsupportedOperationException("Not supported yet.");
+            }
+        }, client.getInputStream(), client.getOutputStream());
+        serverLauncher.startListening();
+        LanguageServer server = serverLauncher.getRemoteProxy();
+        InitializeParams initParams = new InitializeParams();
+        initParams.setRootUri(getWorkDir().toURI().toString());
+        InitializeResult result = server.initialize(initParams).get();
+        indexingComplete.await();
+        server.getTextDocumentService().didOpen(new 
DidOpenTextDocumentParams(new TextDocumentItem(toURI(src), "java", 0, code)));
+        VersionedTextDocumentIdentifier id = new 
VersionedTextDocumentIdentifier(src.toURI().toString(), 1);
+        List<Either<Command, CodeAction>> codeActions = 
server.getTextDocumentService().codeAction(new CodeActionParams(id, new 
Range(new Position(5, 10), new Position(5, 10)), new 
CodeActionContext(Arrays.asList(), 
Arrays.asList(CodeActionKind.Refactor)))).get();
+        Optional<CodeAction> move =
+                codeActions.stream()
+                           .filter(Either::isRight)
+                           .map(Either::getRight)
+                           .filter(a -> Bundle.DN_Move().equals(a.getTitle()))
+                           .findAny();
+        assertTrue(move.isPresent());
+        server.getWorkspaceService().executeCommand(new 
ExecuteCommandParams(move.get().getCommand().getCommand(), 
move.get().getCommand().getArguments())).get();
+        int cnt = 0;
+        while(edit[0] == null && cnt++ < 10) {
+            Thread.sleep(1000);
+        }
+        List<Either<TextDocumentEdit, ResourceOperation>> documentChanges = 
edit[0].getDocumentChanges();
+        assertEquals(2, documentChanges.size());
+        for (int i = 0; i <= 1; i++) {
+            Either<TextDocumentEdit, ResourceOperation> change = 
documentChanges.get(i);
+            assertTrue(change.isLeft());
+            TextDocumentEdit tde = change.getLeft();
+            if (tde.getTextDocument().getUri().endsWith("a/Test.java")) {
+                List<TextEdit> fileChanges = tde.getEdits();
+                assertNotNull(fileChanges);
+                assertEquals(1, fileChanges.size());
+                assertEquals(new Range(new Position(5, 0),
+                                       new Position(6, 0)),
+                             fileChanges.get(0).getRange());
+                assertEquals("", fileChanges.get(0).getNewText());
+            } else if 
(tde.getTextDocument().getUri().endsWith("b/Test2.java")) {
+                List<TextEdit> fileChanges = tde.getEdits();
+                assertNotNull(fileChanges);
+                assertEquals(2, fileChanges.size());
+                assertEquals(new Range(new Position(2, 0),
+                                       new Position(2, 0)),
+                             fileChanges.get(0).getRange());
+                assertEquals("import a.Test;\n\n", 
fileChanges.get(0).getNewText());
+                assertEquals(new Range(new Position(3, 0),
+                                       new Position(3, 0)),
+                             fileChanges.get(1).getRange());
+                assertEquals("\n    void m(Test t) {\n    }\n", 
fileChanges.get(1).getNewText());
+            } else {
+                fail("Unknown file modified");
+            }
+        }
     }
 
     public void testNoErrorAndHintsFor() throws Exception {
@@ -4237,6 +4564,12 @@ public class ServerTest extends NbTestCase {
         @Override
         public ClassPath findClassPath(FileObject file, String type) {
             if (ClassPath.SOURCE.equals(type) && file.isData()) {
+                Project p = FileOwnerQuery.getOwner(file);
+                if (p != null) {
+                    for (SourceGroup sg : 
ProjectUtils.getSources(p).getSourceGroups(JavaProjectConstants.SOURCES_TYPE_JAVA))
 {
+                        return 
ClassPathSupport.createClassPath(sg.getRootFolder());
+                    }
+                }
                 return ClassPathSupport.createClassPath(file.getParent());
             }
             if (ClassPath.BOOT.equals(type)) {
@@ -4315,6 +4648,55 @@ public class ServerTest extends NbTestCase {
                             }
                             return null;
                         }
+                    }, new Sources() {
+                        @Override
+                        public SourceGroup[] getSourceGroups(String type) {
+                            if 
(JavaProjectConstants.SOURCES_TYPE_JAVA.equals(type)) {
+                                return new SourceGroup[] {
+                                    new SourceGroup() {
+                                        private final String name = 
"testSource";
+                                        public FileObject getRootFolder() {
+                                            return projectDirectory;
+                                        }
+
+                                        public String getName() {
+                                            return name;
+                                        }
+
+                                        public String getDisplayName() {
+                                            return name;
+                                        }
+
+                                        public Icon getIcon(boolean opened) {
+                                            return null;
+                                        }
+
+                                        @Override public boolean 
contains(FileObject file) {
+                                            return 
FileUtil.isParentOf(projectDirectory, file);
+                                        }
+
+                                        public void 
addPropertyChangeListener(PropertyChangeListener listener) {
+                                        }
+
+                                        public void 
removePropertyChangeListener(PropertyChangeListener listener) {
+                                        }
+
+                                        public @Override String toString() {
+                                            return name;
+                                        }
+                                    }
+                                };
+                            }
+                            return new SourceGroup[0];
+                        }
+
+                        @Override
+                        public void addChangeListener(ChangeListener listener) 
{
+                        }
+
+                        @Override
+                        public void removeChangeListener(ChangeListener 
listener) {
+                        }
                     }
                 );
                 return new Project() {
diff --git 
a/java/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/MoveFileRefactoringPlugin.java
 
b/java/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/MoveFileRefactoringPlugin.java
index 5a25832..31a53dd 100644
--- 
a/java/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/MoveFileRefactoringPlugin.java
+++ 
b/java/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/MoveFileRefactoringPlugin.java
@@ -579,6 +579,7 @@ public class MoveFileRefactoringPlugin extends 
JavaRefactoringPlugin {
                 } else {
                     deleteFile = new DeleteFile(filesToMove.get(0), elements);
                 }
+                elements.addFileChange(refactoring, deleteFile);
                 elements.add(refactoring, deleteFile);
             }
             problem = moveClassTransformer.getProblem();

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists

Reply via email to