You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@netbeans.apache.org by GitBox <gi...@apache.org> on 2017/11/09 08:10:13 UTC

[GitHub] JaroslavTulach closed pull request #259: Sdedic/netbeans bugfixes

JaroslavTulach closed pull request #259: Sdedic/netbeans bugfixes
URL: https://github.com/apache/incubator-netbeans/pull/259
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/core.windows/manifest.mf b/core.windows/manifest.mf
index d7d2643fa..734655d83 100644
--- a/core.windows/manifest.mf
+++ b/core.windows/manifest.mf
@@ -6,5 +6,5 @@ OpenIDE-Module-Provides: org.netbeans.core.WindowSystem, org.openide.windows.Win
 OpenIDE-Module-Recommends: org.netbeans.core.windows.nativeaccess.NativeWindowSystem
 AutoUpdate-Show-In-Client: false
 AutoUpdate-Essential-Module: true
-OpenIDE-Module-Specification-Version: 2.82
+OpenIDE-Module-Specification-Version: 2.83
 
diff --git a/core.windows/src/org/netbeans/core/windows/WindowManagerImpl.java b/core.windows/src/org/netbeans/core/windows/WindowManagerImpl.java
index 50f3cb164..35c3b7b06 100644
--- a/core.windows/src/org/netbeans/core/windows/WindowManagerImpl.java
+++ b/core.windows/src/org/netbeans/core/windows/WindowManagerImpl.java
@@ -1214,6 +1214,14 @@ protected void topComponentOpenAtTabPosition (TopComponent tc, int position) {
         
         if (mode == null) {
             mode = getDefaultEditorModeForOpen();
+            Collection<? extends ModeSelector> selectors = Lookup.getDefault().lookupAll(ModeSelector.class);
+            for (ModeSelector s : selectors) {
+                Mode hintMode = s.selectModeForOpen(tc, mode);
+                if (hintMode instanceof ModeImpl) {
+                    mode = (ModeImpl)hintMode;
+                    break;
+                }
+            }
             assert getModes().contains(mode) : "Mode " + mode.getName() + " is not in model."; //NOI18N
             if (tc.getClientProperty (Constants.TOPCOMPONENT_ALLOW_DOCK_ANYWHERE) == null) {
                 tc.putClientProperty (Constants.TOPCOMPONENT_ALLOW_DOCK_ANYWHERE, Boolean.TRUE);
diff --git a/editor.fold.nbui/src/org/netbeans/modules/editor/fold/ui/FoldViewFactory.java b/editor.fold.nbui/src/org/netbeans/modules/editor/fold/ui/FoldViewFactory.java
index ecdb3c5da..742f29394 100644
--- a/editor.fold.nbui/src/org/netbeans/modules/editor/fold/ui/FoldViewFactory.java
+++ b/editor.fold.nbui/src/org/netbeans/modules/editor/fold/ui/FoldViewFactory.java
@@ -26,6 +26,7 @@
 import java.util.prefs.PreferenceChangeListener;
 import java.util.prefs.Preferences;
 import javax.swing.text.Document;
+import javax.swing.text.JTextComponent;
 import javax.swing.text.View;
 import org.netbeans.api.editor.fold.Fold;
 import org.netbeans.api.editor.fold.FoldHierarchy;
@@ -40,6 +41,7 @@
 import org.netbeans.modules.editor.lib2.view.EditorViewFactory;
 import org.netbeans.modules.editor.lib2.view.EditorViewFactoryChange;
 import org.netbeans.modules.editor.lib2.view.ViewUtils;
+import org.openide.util.Exceptions;
 import org.openide.util.Lookup;
 import org.openide.util.LookupEvent;
 import org.openide.util.LookupListener;
@@ -276,8 +278,8 @@ public void foldHierarchyChanged(FoldHierarchyEvent evt) {
                 }
             }
         }
-
-        if (collapsedFoldEncountered) {
+        JTextComponent comp = textComponent();
+        if (collapsedFoldEncountered && comp != null) {
             // [TODO] there could be more detailed inspection done among folds
             // of what really changed and what are in fact the same folds as before the change
             // possibly performed even on the Fold API level.
@@ -287,6 +289,7 @@ public void foldHierarchyChanged(FoldHierarchyEvent evt) {
                 ViewUtils.log(CHANGE_LOG, "CHANGE in FoldViewFactory: <" + // NOI18N
                         startOffset + "," + endOffset + ">\n"); // NOI18N
             }
+            comp.putClientProperty("editorcaret.updateRetainsVisibleOnce", Boolean.TRUE);
             fireEvent(EditorViewFactoryChange.createList(startOffset, endOffset,
                     EditorViewFactoryChange.Type.PARAGRAPH_CHANGE));
         }
diff --git a/editor.lib2/src/org/netbeans/api/editor/caret/EditorCaret.java b/editor.lib2/src/org/netbeans/api/editor/caret/EditorCaret.java
index 3ff18b626..24f22c484 100644
--- a/editor.lib2/src/org/netbeans/api/editor/caret/EditorCaret.java
+++ b/editor.lib2/src/org/netbeans/api/editor/caret/EditorCaret.java
@@ -1021,6 +1021,41 @@ public void deinstall(JTextComponent c) {
         
         modelChanged(activeDoc, null);
     }
+    
+    /**
+     * Saves relative position of the 'main' caret for the case that fold view
+     * update is underway - this update should maintain caret visual position on screen.
+     * For that, the nearest update must reposition scroller's viewrect so that the 
+     * recomputed caretBounds is at the same
+     */
+    private synchronized void maybeSaveCaretOffset(JTextComponent c, Rectangle cbounds) {
+        if (c.getClientProperty("editorcaret.updateRetainsVisibleOnce")  == null || // NOI18N
+            lastCaretVisualOffset != -1) {
+           return; 
+        }
+        Component parent = c.getParent();
+        Rectangle editorRect;
+        if (parent instanceof JLayeredPane) {
+            parent = parent.getParent();
+        }
+        if (parent instanceof JViewport) {
+            final JViewport viewport = (JViewport) parent;
+            editorRect = viewport.getViewRect();
+        } else {
+            Dimension size = c.getSize();
+            editorRect = new Rectangle(0, 0, size.width, size.height);
+        }
+        if (cbounds.y >= editorRect.y && cbounds.y < (editorRect.y + editorRect.height)) {
+            lastCaretVisualOffset = (cbounds.y - editorRect.y);
+            if (LOG.isLoggable(Level.FINER)) {
+                LOG.fine("EditorCaret: saving caret offset. Bounds = " + cbounds + ", editor = " + editorRect + ", offset = " + lastCaretVisualOffset);
+            }
+        } else {
+            if (LOG.isLoggable(Level.FINER)) {
+                LOG.fine("EditorCaret: caret is off screen. Bounds = " + cbounds + ", editor = " + editorRect);
+            }
+        }
+    }
 
     @Override
     public void paint(Graphics g) {
@@ -1042,6 +1077,7 @@ public void paint(Graphics g) {
                 // Find the first caret to be painted
                 // Only paint carets that are part of the clip - use sorted carets
                 List<CaretInfo> sortedCarets = getSortedCarets();
+                CaretItem lastCaret = getLastCaretItem();
                 int low = 0;
                 int caretsSize = sortedCarets.size();
                 if (caretsSize > 1) {
@@ -1071,7 +1107,10 @@ public void paint(Graphics g) {
                     if (caretItem.getAndClearUpdateCaretBounds()) {
                         int dot = caretItem.getDot();
                         Rectangle newCaretBounds = lvh.modelToViewBounds(dot, Position.Bias.Forward);
-                        caretItem.setCaretBoundsWithRepaint(newCaretBounds, c, "EditorCaret.paint()", i);
+                        Rectangle oldBounds = caretItem.setCaretBoundsWithRepaint(newCaretBounds, c, "EditorCaret.paint()", i);
+                        if (caretItem == lastCaret) {
+                            maybeSaveCaretOffset(c, oldBounds);
+                        }
                     }
                     Rectangle caretBounds = caretItem.getCaretBounds();
                     if (caretBounds != null) {
@@ -1895,6 +1934,13 @@ private void dispatchUpdate(boolean forceInvokeLater) {
             }
         }
     }
+    
+    /**
+     * Pixel distance of the caret, from the top of the editor view. Saved on the before caret position changes
+     * when editorcaret.updateRetainsVisibleOnce (set by folding on the text component) is present. During update,
+     * the distance is used to maintain caret position on screen, assuming view hierarchy changed (folds have collapsed).
+     */
+    private int lastCaretVisualOffset = -1;
 
     /**
      * Update the caret's visual position.
@@ -1911,10 +1957,7 @@ private void update(boolean calledFromPaint) {
         }
         final JTextComponent c = component;
         if (c != null) {
-            if (!calledFromPaint && !c.isValid()) {
-                updateLaterDuringPaint = true;
-                return;
-            }
+            boolean forceUpdate = c.getClientProperty("editorcaret.updateRetainsVisibleOnce") != null;
             boolean log = LOG.isLoggable(Level.FINE);
             Component parent = c.getParent();
             Rectangle editorRect;
@@ -1922,12 +1965,22 @@ private void update(boolean calledFromPaint) {
                 parent = parent.getParent();
             }
             if (parent instanceof JViewport) {
-                JViewport viewport = (JViewport) parent;
+                final JViewport viewport = (JViewport) parent;
                 editorRect = viewport.getViewRect();
             } else {
                 Dimension size = c.getSize();
                 editorRect = new Rectangle(0, 0, size.width, size.height);
             }
+            if (forceUpdate) {
+                Rectangle cbounds = getLastCaretItem().getCaretBounds();
+                // save relative position of the main caret
+                maybeSaveCaretOffset(c, cbounds);
+            }
+            if (!calledFromPaint && !c.isValid() /* && maintainVisible == null */) {
+                updateLaterDuringPaint = true;
+                return;
+            }
+
             Document doc = c.getDocument();
             if (doc != null) {
                 if (log) {
@@ -1947,7 +2000,7 @@ private void update(boolean calledFromPaint) {
                         scroll = scrollToLastCaret;
                         scrollToLastCaret = false;
                     }
-                    if (scroll) {
+                    if (scroll || forceUpdate) {
                         Rectangle caretBounds;
                         Rectangle oldCaretBounds;
                         if (lastCaretItem.getAndClearUpdateCaretBounds()) {
@@ -1984,14 +2037,24 @@ private void update(boolean calledFromPaint) {
                                     }
                                 }
                             }
+                            if (forceUpdate && oldCaretBounds != null) {
+                                c.putClientProperty("editorcaret.updateRetainsVisibleOnce", null);
+                                if (lastCaretVisualOffset >= 0) {
+                                    // change scroll to so that caret will maintain its relative position saved before the caret was changed.
+                                    scrollBounds = new Rectangle(caretBounds.x, caretBounds.y - lastCaretVisualOffset, scrollBounds.width, editorRect.height);
+                                }
+                                lastCaretVisualOffset = -1;
+                            }
                             if (editorRect == null || !editorRect.contains(scrollBounds)) {
                                 Rectangle visibleBounds = c.getVisibleRect();
-                                if (// #219580: if the preceding if-block computed new scrollBounds, it cannot be offset yet more
-                                        /* # 70915 !updateAfterFoldHierarchyChange && */ (caretBounds.y > visibleBounds.y + visibleBounds.height + caretBounds.height
-                                        || caretBounds.y + caretBounds.height < visibleBounds.y - caretBounds.height)) {
-                                    // Scroll into the middle
-                                    scrollBounds.y -= (visibleBounds.height - caretBounds.height) / 2;
-                                    scrollBounds.height = visibleBounds.height;
+                                if (!forceUpdate) {
+                                    if (// #219580: if the preceding if-block computed new scrollBounds, it cannot be offset yet more
+                                            /* # 70915 !updateAfterFoldHierarchyChange && */ (caretBounds.y > visibleBounds.y + visibleBounds.height + caretBounds.height
+                                            || caretBounds.y + caretBounds.height < visibleBounds.y - caretBounds.height)) {
+                                        // Scroll into the middle
+                                        scrollBounds.y -= (visibleBounds.height - caretBounds.height) / 2;
+                                        scrollBounds.height = visibleBounds.height;
+                                    }
                                 }
                                 // When typing on a longest line the size of the component may still not incorporate just performed insert
                                 // at this point so schedule the scrolling for later.
diff --git a/java.completion/src/org/netbeans/modules/java/completion/BaseTask.java b/java.completion/src/org/netbeans/modules/java/completion/BaseTask.java
index d3c84f17e..1597def64 100644
--- a/java.completion/src/org/netbeans/modules/java/completion/BaseTask.java
+++ b/java.completion/src/org/netbeans/modules/java/completion/BaseTask.java
@@ -56,18 +56,44 @@
 
     protected final int caretOffset;
     protected final Callable<Boolean> cancel;
+    private int caretInSnapshot;
 
     protected BaseTask(int caretOffset, Callable<Boolean> cancel) {
         this.caretOffset = caretOffset;
         this.cancel = cancel;
     }
 
+    
+    final int getCaretInSnapshot() {
+        return caretInSnapshot;
+    }
+    
+    private CompilationController controller;
+    
+    final int snapshotPos(int pos) {
+        if (pos < 0) {
+            return pos;
+        }
+        int r = controller.getSnapshot().getEmbeddedOffset(pos);
+        if (r == -1) {
+            return pos;
+        } else {
+            return r;
+        }
+    }
+
     @Override
     public void run(ResultIterator resultIterator) throws Exception {
         Parser.Result result = resultIterator.getParserResult(caretOffset);
         CompilationController controller = result != null ? CompilationController.get(result) : null;
         if (controller != null && (cancel == null || !cancel.call())) {
-            resolve(controller);
+            try {
+                this.controller = controller;
+                caretInSnapshot = snapshotPos(caretOffset);
+                resolve(controller);
+            } finally {
+                this.controller = null;
+            }
         }
     }
 
@@ -342,8 +368,8 @@ private Env getEnvImpl(CompilationController controller, TreePath orig, TreePath
                     if (blockPath.getParentPath().getLeaf().getKind() == Tree.Kind.METHOD
                             || TreeUtilities.CLASS_TREE_KINDS.contains(blockPath.getParentPath().getLeaf().getKind())) {
                         final int blockPos = (int) sourcePositions.getStartPosition(root, blockPath.getLeaf());
-                        final String blockText = upToOffset && caretOffset > offset
-                                ? controller.getText().substring(blockPos, offset) + whitespaceString(caretOffset - offset) + controller.getText().substring(caretOffset, (int) sourcePositions.getEndPosition(root, blockPath.getLeaf()))
+                        final String blockText = upToOffset && getCaretInSnapshot() > offset
+                                ? controller.getText().substring(blockPos, offset) + whitespaceString(getCaretInSnapshot() - offset) + controller.getText().substring(getCaretInSnapshot(), (int) sourcePositions.getEndPosition(root, blockPath.getLeaf()))
                                 : controller.getText().substring(blockPos, (int) sourcePositions.getEndPosition(root, blockPath.getLeaf()));
                         final SourcePositions[] sp = new SourcePositions[1];
                         final StatementTree block = (((BlockTree) blockPath.getLeaf()).isStatic() ? tu.parseStaticBlock(blockText, sp) : tu.parseStatement(blockText, sp));
diff --git a/java.editor/src/org/netbeans/modules/java/editor/imports/ComputeImports.java b/java.editor/src/org/netbeans/modules/java/editor/imports/ComputeImports.java
index 928c085cf..4662e67e4 100644
--- a/java.editor/src/org/netbeans/modules/java/editor/imports/ComputeImports.java
+++ b/java.editor/src/org/netbeans/modules/java/editor/imports/ComputeImports.java
@@ -34,6 +34,7 @@
 import com.sun.source.tree.Tree.Kind;
 import com.sun.source.tree.VariableTree;
 import com.sun.source.util.TreePath;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -68,17 +69,26 @@
 import org.netbeans.api.annotations.common.NonNull;
 import org.netbeans.api.annotations.common.NullAllowed;
 import org.netbeans.api.editor.mimelookup.MimeLookup;
+import org.netbeans.api.java.classpath.ClassPath;
 import org.netbeans.api.java.lexer.JavaTokenId;
 import org.netbeans.api.java.source.ClassIndex;
 import org.netbeans.api.java.source.CompilationInfo;
 import org.netbeans.api.java.source.ClassIndex.NameKind;
 import org.netbeans.api.java.source.ClassIndex.Symbols;
+import org.netbeans.api.java.source.ClasspathInfo;
+import org.netbeans.api.java.source.CompilationController;
 import org.netbeans.api.java.source.CompilationInfo.CacheClearPolicy;
 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.support.CancellableTreePathScanner;
 import org.netbeans.modules.java.completion.Utilities;
 import org.netbeans.modules.java.editor.base.javadoc.JavadocImports;
+import org.netbeans.modules.parsing.api.ResultIterator;
+import org.netbeans.modules.parsing.api.UserTask;
+import org.netbeans.spi.java.classpath.support.ClassPathSupport;
+import org.openide.util.Exceptions;
 import org.openide.util.Union2;
 import org.openide.util.WeakListeners;
 
@@ -98,6 +108,8 @@ public ComputeImports(final CompilationInfo info) {
     }
     
     private final CompilationInfo info;
+    private CompilationInfo allInfo;
+    
     private final PreferenceChangeListener pcl = new PreferenceChangeListener() {
         @Override
         public void preferenceChange(PreferenceChangeEvent evt) {
@@ -158,7 +170,42 @@ public ComputeImports computeCandidatesEx() {
         if (cache != null) {
             return cache;
         }
-        computeCandidates(Collections.<String>emptySet());
+        boolean modules = false;
+        
+        if (info.getSourceVersion().compareTo(SourceVersion.RELEASE_9) <= 0) {
+            if (info.getClasspathInfo().getClassPath(ClasspathInfo.PathKind.SOURCE).findResource("module-info.java") != null) {
+                modules = true;
+            }
+        }
+        
+        if (modules) {
+            ClasspathInfo cpInfo = info.getClasspathInfo();
+            ClasspathInfo extraInfo = ClasspathInfo.create(
+                    ClassPathSupport.createProxyClassPath(
+                            cpInfo.getClassPath(ClasspathInfo.PathKind.BOOT),
+                            cpInfo.getClassPath(ClasspathInfo.PathKind.MODULE_BOOT)),
+                    ClassPathSupport.createProxyClassPath(
+                            cpInfo.getClassPath(ClasspathInfo.PathKind.COMPILE),
+                            cpInfo.getClassPath(ClasspathInfo.PathKind.MODULE_COMPILE),
+                            cpInfo.getClassPath(ClasspathInfo.PathKind.MODULE_CLASS)),
+                    cpInfo.getClassPath(ClasspathInfo.PathKind.SOURCE));
+            JavaSource src = JavaSource.create(extraInfo, info.getSnapshot().getSource().getFileObject());
+            try {
+                src.runUserActionTask(new Task<CompilationController>() {
+                    @Override
+                    public void run(CompilationController parameter) throws Exception {
+                        allInfo = parameter;
+                        parameter.toPhase(JavaSource.Phase.RESOLVED);
+                        computeCandidates(Collections.<String>emptySet());
+                    }
+                }, true);
+            } catch (IOException ex) {
+                Exceptions.printStackTrace(ex);
+            }
+        } else {
+            allInfo = info;
+            computeCandidates(Collections.<String>emptySet());
+        }
         info.putCachedValue(IMPORT_CANDIDATES_KEY, this, CacheClearPolicy.ON_CHANGE);
         return this;
     }
@@ -179,8 +226,7 @@ private synchronized void setVisitor(TreeVisitorImpl visitor) {
     
     Pair<Map<String, List<Element>>, Map<String, List<Element>>> computeCandidates(Set<String> forcedUnresolved) {
         final CompilationUnitTree cut = info.getCompilationUnit();
-        Element el = info.getTrees().getElement(new TreePath(cut));
-        ModuleElement modle = el != null ? info.getElements().getModuleOf(el) : null;
+        ClasspathInfo cpInfo = allInfo.getClasspathInfo();
         final TreeVisitorImpl v = new TreeVisitorImpl(info);
         setVisitor(v);
         try {
@@ -200,7 +246,7 @@ private synchronized void setVisitor(TreeVisitorImpl visitor) {
                 return null;
             
             List<Element> classes = new ArrayList<Element>();
-            Set<ElementHandle<TypeElement>> typeNames = info.getClasspathInfo().getClassIndex().getDeclaredTypes(unresolved, NameKind.SIMPLE_NAME,EnumSet.allOf(ClassIndex.SearchScope.class));
+            Set<ElementHandle<TypeElement>> typeNames = cpInfo.getClassIndex().getDeclaredTypes(unresolved, NameKind.SIMPLE_NAME,EnumSet.allOf(ClassIndex.SearchScope.class));
             if (typeNames == null) {
                 //Canceled
                 return null;
@@ -208,8 +254,7 @@ private synchronized void setVisitor(TreeVisitorImpl visitor) {
             for (ElementHandle<TypeElement> typeName : typeNames) {
                 if (isCancelled())
                     return null;
-
-                TypeElement te = modle != null ? info.getElements().getTypeElement(modle, typeName.getQualifiedName()) : info.getElements().getTypeElement(typeName.getQualifiedName());
+                TypeElement te = typeName.resolve(allInfo);
                 
                 if (te == null) {
                     Logger.getLogger(ComputeImports.class.getName()).log(Level.INFO, "Cannot resolve type element \"" + typeName + "\".");
@@ -223,7 +268,7 @@ private synchronized void setVisitor(TreeVisitorImpl visitor) {
                 }
             }
             
-            Iterable<Symbols> simpleNames = info.getClasspathInfo().getClassIndex().getDeclaredSymbols(unresolved, NameKind.SIMPLE_NAME,EnumSet.allOf(ClassIndex.SearchScope.class));
+            Iterable<Symbols> simpleNames = cpInfo.getClassIndex().getDeclaredSymbols(unresolved, NameKind.SIMPLE_NAME,EnumSet.allOf(ClassIndex.SearchScope.class));
 
             if (simpleNames == null) {
                 //Canceled:
@@ -234,7 +279,7 @@ private synchronized void setVisitor(TreeVisitorImpl visitor) {
                 if (isCancelled())
                     return null;
 
-                final TypeElement te = p.getEnclosingType().resolve(info);
+                final TypeElement te = p.getEnclosingType().resolve(allInfo);
                 final Set<String> idents = p.getSymbols();
                 if (te != null) {
                     for (Element ne : te.getEnclosedElements()) {
@@ -263,7 +308,7 @@ private synchronized void setVisitor(TreeVisitorImpl visitor) {
             fqn2Methods.clear();
             
             for (Hint hint: v.hints) {
-                wasChanged |= hint.filter(info, this);
+                wasChanged |= hint.filter(allInfo, this);
             }
         }
         
diff --git a/java.hints/src/org/netbeans/modules/java/hints/AssignResultToVariable.java b/java.hints/src/org/netbeans/modules/java/hints/AssignResultToVariable.java
index a49205534..5635dfb13 100644
--- a/java.hints/src/org/netbeans/modules/java/hints/AssignResultToVariable.java
+++ b/java.hints/src/org/netbeans/modules/java/hints/AssignResultToVariable.java
@@ -42,6 +42,7 @@
 import java.util.regex.Pattern;
 import javax.lang.model.element.Element;
 import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ExecutableElement;
 import javax.lang.model.element.Modifier;
 import javax.lang.model.type.TypeKind;
 import javax.lang.model.type.TypeMirror;
@@ -159,6 +160,14 @@ public AssignResultToVariable() {
             TypeMirror type = Utilities.resolveTypeForDeclaration(
                     info, base
             );
+            if (!error && !Utilities.isValidType(base)) {
+                if (treePath.getLeaf().getKind() == Tree.Kind.METHOD_INVOCATION) {
+                    TypeMirror retType = ((ExecutableElement)elem).getReturnType();
+                    if (!info.getTypes().isAssignable(info.getTypes().erasure(retType), info.getTypes().erasure(type))) {
+                        return null;
+                    }
+                }
+            }
             
             // could use Utilities.isValidType, but NOT_ACCEPTABLE_TYPE_KINDS does the check as well
             if (type == null || NOT_ACCEPTABLE_TYPE_KINDS.contains(type.getKind())) {
diff --git a/java.hints/src/org/netbeans/modules/java/hints/errors/ImportClass.java b/java.hints/src/org/netbeans/modules/java/hints/errors/ImportClass.java
index e9b0307ef..31671c6ac 100644
--- a/java.hints/src/org/netbeans/modules/java/hints/errors/ImportClass.java
+++ b/java.hints/src/org/netbeans/modules/java/hints/errors/ImportClass.java
@@ -20,13 +20,18 @@
 package org.netbeans.modules.java.hints.errors;
 
 import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.tree.DirectiveTree;
 import com.sun.source.tree.IdentifierTree;
 import com.sun.source.tree.ImportTree;
 import com.sun.source.tree.MemberSelectTree;
+import com.sun.source.tree.ModuleTree;
+import com.sun.source.tree.RequiresTree;
 import com.sun.source.tree.Tree;
 import com.sun.source.tree.Tree.Kind;
 import com.sun.source.util.TreePath;
+import com.sun.source.util.TreeScanner;
 import java.io.IOException;
+import java.net.URL;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -38,19 +43,27 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import java.util.prefs.Preferences;
+import java.util.stream.Collectors;
 import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.TypeElement;
 import javax.swing.text.Document;
 import org.netbeans.api.annotations.common.NullAllowed;
 import org.netbeans.api.editor.mimelookup.MimeLookup;
 import org.netbeans.api.editor.mimelookup.MimePath;
+import org.netbeans.api.java.classpath.ClassPath;
 import org.netbeans.api.java.lexer.JavaTokenId;
+import org.netbeans.api.java.source.ClasspathInfo;
 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.ElementHandle;
 import org.netbeans.api.java.source.GeneratorUtilities;
 import org.netbeans.api.java.source.JavaSource;
 import org.netbeans.api.java.source.JavaSource.Phase;
+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.api.java.source.support.ReferencesCount;
@@ -69,9 +82,12 @@
 import org.netbeans.spi.editor.hints.ChangeInfo;
 import org.netbeans.spi.editor.hints.EnhancedFix;
 import org.netbeans.spi.editor.hints.Fix;
+import org.netbeans.spi.java.classpath.support.ClassPathSupport;
 import org.openide.awt.StatusDisplayer;
 import org.openide.cookies.EditorCookie;
+import org.openide.cookies.SaveCookie;
 import org.openide.filesystems.FileObject;
+import org.openide.filesystems.URLMapper;
 import org.openide.loaders.DataObject;
 import org.openide.loaders.DataObjectNotFoundException;
 import org.openide.util.Exceptions;
@@ -359,9 +375,11 @@ private FixBase(FileObject file, String fqn, ElementHandle<Element> toImport, St
             this.sortText = sortText;
         }
         
-        protected abstract void perform();
+        protected abstract boolean perform();
         protected abstract void performDoc(Document doc);
-    
+        
+        private boolean needsChange;
+        
         public ChangeInfo implement() throws IOException {
             JavaSource js = JavaSource.forFileObject(file);            
             
@@ -372,14 +390,17 @@ public void run(WorkingCopy copy) throws Exception {
                     }
                     FixBase.this.copy = copy;
                     try {
-                        perform();
+                        needsChange = false; // for case of an error
+                        needsChange = perform();
                     } finally {
                         FixBase.this.copy = null;
                     }
                 }
             };
             if (js != null) {
-                js.runModificationTask(task).commit();
+                do {
+                    js.runModificationTask(task).commit();
+                } while (needsChange);
             } else {
                 DataObject od;
                 
@@ -458,16 +479,16 @@ void addTreePath(TreePathHandle toReplace) {
         }
 
         @Override
-        protected void perform() {
+        protected boolean perform() {
             TreePath replacePath = replacePathHandle.resolve(copy);
 
             if (replacePath == null) {
                 Logger.getAnonymousLogger().warning(String.format("Attempt to change import for FQN: %s, but the import cannot be resolved in the current context", fqn));
-                return;
+                return false;
             }
             Element el = toImport.resolve(copy);
             if (el == null) {
-                return;
+                return false;
             }
             CharSequence elFQN = copy.getElementUtilities().getElementName(el, true);
             IdentifierTree id = copy.getTreeMaker().Identifier(elFQN);
@@ -480,6 +501,7 @@ protected void perform() {
                 }
                 copy.rewrite(replacePath.getLeaf(), id);
             }
+            return false;
         }
 
         @Override
@@ -515,6 +537,9 @@ public boolean equals(Object o) {
         private final @NullAllowed String suffix;
         private final boolean statik;
         private final boolean doOrganize;
+        String requiresModName;
+        boolean moduleAdded;
+        int round;
         
         public FixImport(FileObject file, String fqn, ElementHandle<Element> toImport, String sortText, boolean isValid, CompilationInfo info, @NullAllowed TreePath replacePath, @NullAllowed String replaceSuffix, 
                 boolean doOrganize) {
@@ -559,25 +584,95 @@ protected void performDoc(Document doc) {
         }
 
         @Override
-        protected void perform() {
+        protected boolean perform() {
+            round++;
             if (replacePathHandle != null) {
                 TreePath replacePath = replacePathHandle.resolve(copy);
 
                 if (replacePath == null) {
                     Logger.getAnonymousLogger().warning(String.format("Attempt to change import for FQN: %s, but the import cannot be resolved in the current context", fqn));
-                    return;
+                    return false;
                 }
 
                 copy.rewrite(replacePath.getLeaf(), copy.getTreeMaker().Identifier(fqn));
-
-                return;
+                return false;
             }
 
             Element te = toImport.resolve(copy);
-
+            JavaSource modInfoSrc = null;
+            if (te == null && round < 2) {
+                // check if the project is Source Level 9 and the sources indeed contain module-info.java
+                FileObject modInfo = org.netbeans.modules.java.hints.errors.Utilities.getModuleInfo(copy);
+                if (modInfo != null) {
+                    // attempt to resolve/find the elememt in the dependencies, then add the correct module.
+                    ClasspathInfo cpInfo = copy.getClasspathInfo();
+                    ClasspathInfo extraInfo = ClasspathInfo.create(
+                            ClassPathSupport.createProxyClassPath(
+                                    cpInfo.getClassPath(ClasspathInfo.PathKind.BOOT),
+                                    cpInfo.getClassPath(ClasspathInfo.PathKind.MODULE_BOOT)),
+                            ClassPathSupport.createProxyClassPath(
+                                    cpInfo.getClassPath(ClasspathInfo.PathKind.COMPILE),
+                                    cpInfo.getClassPath(ClasspathInfo.PathKind.MODULE_COMPILE),
+                                    cpInfo.getClassPath(ClasspathInfo.PathKind.MODULE_CLASS)),
+                            cpInfo.getClassPath(ClasspathInfo.PathKind.SOURCE));
+                    modInfoSrc = JavaSource.create(extraInfo, modInfo);
+                    try {
+                        modInfoSrc.runUserActionTask(new Task<CompilationController>() {
+                            @Override
+                            public void run(CompilationController parameter) throws Exception {
+                                parameter.toPhase(Phase.RESOLVED);
+                                Element x = toImport.resolve(parameter);
+                                if (x == null) {
+                                    return;
+                                }
+                                // find the toplevel class:
+                                
+                                while (x.getEnclosingElement() != null && x.getEnclosingElement().getKind() != ElementKind.PACKAGE) {
+                                    x = x.getEnclosingElement();
+                                }
+                                if (x == null || !(x.getKind().isClass() || x.getKind().isInterface())) {
+                                    return;
+                                }
+                                TypeElement tel = (TypeElement)x;
+                                String res = tel.getQualifiedName().toString().replace('.', '/');
+                                ClassPath compPath = ClassPathSupport.createProxyClassPath(
+                                        extraInfo.getClassPath(ClasspathInfo.PathKind.BOOT),
+                                        extraInfo.getClassPath(ClasspathInfo.PathKind.COMPILE));
+                                FileObject f = compPath.findResource(res + ".class");
+                                if (f == null) {
+                                    return;
+                                }
+                                FileObject rf = compPath.findOwnerRoot(f);
+                                URL u = URLMapper.findURL(rf, URLMapper.INTERNAL);
+                                if (u == null) {
+                                    return;
+                                }
+                                requiresModName = SourceUtils.getModuleName(u);
+                            }
+                        }, true);
+                        if (requiresModName == null) {
+                            Logger.getAnonymousLogger().warning(String.format("Attempt to fix import for FQN: %s, which does not have a TypeElement in currect context", fqn));
+                            return false;
+                        }
+                        Set<String> modules = new HashSet<>();
+                        modules.add(requiresModName);
+                        addRequiredModules(modInfo, modInfoSrc, modules);
+                        if (moduleAdded) {
+                            te = toImport.resolve(copy);
+                            // make the actual import in the next round
+                            return true;
+                        } else {
+                            Logger.getAnonymousLogger().warning(String.format("Could not add module %s for fqn %s", requiresModName, fqn));
+                            return false;
+                        }
+                    } catch (IOException ex) {
+                        Exceptions.printStackTrace(ex);
+                    }
+                }
+            }
             if (te == null) {
                 Logger.getAnonymousLogger().warning(String.format("Attempt to fix import for FQN: %s, which does not have a TypeElement in currect context", fqn));
-                return ;
+                return false;
             }
 
             if (doOrganize) {
@@ -589,6 +684,62 @@ protected void perform() {
                 );                        
                 copy.rewrite(copy.getCompilationUnit(), cut);
             }
+            return false;
+        }
+        
+        private void addRequiredModules(FileObject fo, JavaSource js, Set<String> moduleNames) throws IOException {
+            js.runModificationTask((wc) -> {
+                wc.toPhase(JavaSource.Phase.RESOLVED);
+                final CompilationUnitTree cu = wc.getCompilationUnit();
+                final Set<String> knownModules = new HashSet<>();
+                final ModuleTree[] module = new ModuleTree[1];
+                final RequiresTree[] lastRequires = new RequiresTree[1];
+                cu.accept(new TreeScanner<Void, Void>() {
+                            @Override
+                            public Void visitModule(ModuleTree m, Void p) {
+                                module[0] = m;
+                                return super.visitModule(m, p);
+                            }
+                            @Override
+                            public Void visitRequires(RequiresTree r, Void p) {
+                                lastRequires[0] = r;
+                                knownModules.add(r.getModuleName().toString());
+                                return super.visitRequires(r, p);
+                            }
+                        },
+                        null);
+                if (module[0] != null) {
+                    moduleNames.removeAll(knownModules);
+                    moduleAdded = !moduleNames.isEmpty();
+                    final TreeMaker tm = wc.getTreeMaker();
+                    final List<RequiresTree> newRequires = moduleNames.stream()
+                            .map((name) -> tm.Requires(false, false, tm.QualIdent(name)))
+                            .collect(Collectors.toList());
+
+                    final List<DirectiveTree> newDirectives = new ArrayList<>(
+                            module[0].getDirectives().size() + newRequires.size());
+                    if (lastRequires[0] == null) {
+                        newDirectives.addAll(newRequires);
+                    }
+                    for (DirectiveTree dt : module[0].getDirectives()) {
+                        newDirectives.add(dt);
+                        if (dt == lastRequires[0]) {
+                            newDirectives.addAll(newRequires);
+                        }
+                    }
+                    final ModuleTree newModule = tm.Module(
+                            tm.Modifiers(0, module[0].getAnnotations()),
+                            module[0].getModuleType(),
+                            module[0].getName(),
+                            newDirectives);
+                    wc.rewrite(module[0], newModule);
+                }                    
+            }).commit();
+            // needs to be saved so that resolution will consider the added module
+            SaveCookie s = fo.getLookup().lookup(SaveCookie.class);
+            if (s != null) {
+                s.save();
+            }
         }
     }
 }
diff --git a/java.hints/src/org/netbeans/modules/java/hints/errors/Utilities.java b/java.hints/src/org/netbeans/modules/java/hints/errors/Utilities.java
index 18afd9bd3..d014c65fa 100644
--- a/java.hints/src/org/netbeans/modules/java/hints/errors/Utilities.java
+++ b/java.hints/src/org/netbeans/modules/java/hints/errors/Utilities.java
@@ -143,6 +143,7 @@
 import javax.tools.Diagnostic;
 import javax.tools.JavaFileObject;
 import javax.tools.SimpleJavaFileObject;
+import org.netbeans.api.java.source.ClasspathInfo;
 import org.netbeans.api.java.source.CodeStyle;
 import org.netbeans.api.java.source.CodeStyleUtils;
 import org.netbeans.api.java.source.TreeMaker;
@@ -1598,6 +1599,10 @@ public static boolean isValidElement(Element e) {
         return e != null && isValidType(e.asType());
     }
     
+    public static boolean isValidValueType(TypeMirror m) {
+        return isValidType(m) && m.getKind() != TypeKind.EXECUTABLE;
+    }
+    
     public static boolean isValidType(TypeMirror m) {
         return m != null && (
                 m.getKind() != TypeKind.PACKAGE &&
@@ -2979,4 +2984,15 @@ private static ExpressionTree negateBinaryOperator(TreeMaker make, Tree original
         }
         return make.Binary(newKind, left, right);
     }
+    
+    public static FileObject getModuleInfo(CompilationInfo info) {
+        if (info.getSourceVersion().compareTo(SourceVersion.RELEASE_9) > 0) {
+            return null;
+        }
+        return info.getClasspathInfo().getClassPath(ClasspathInfo.PathKind.SOURCE).findResource("module-info.java");
+    }
+    
+    public static boolean isModular(CompilationInfo info) {
+        return getModuleInfo(info) != null;
+    }
 }
diff --git a/java.hints/src/org/netbeans/modules/java/hints/introduce/FieldValidator.java b/java.hints/src/org/netbeans/modules/java/hints/introduce/FieldValidator.java
index 3bae867a5..edc8e757d 100644
--- a/java.hints/src/org/netbeans/modules/java/hints/introduce/FieldValidator.java
+++ b/java.hints/src/org/netbeans/modules/java/hints/introduce/FieldValidator.java
@@ -18,7 +18,12 @@
  */
 package org.netbeans.modules.java.hints.introduce;
 
+import com.sun.source.tree.BlockTree;
+import com.sun.source.tree.CatchTree;
 import com.sun.source.tree.Scope;
+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.Map;
@@ -43,14 +48,16 @@
 final class FieldValidator implements MemberValidator {
     private final JavaSource            theSource;
     private final TypeMirrorHandle      fieldTypeHandle;
+    private final TreePathHandle        srcHandle;
     
     private String             name;
     private ElementHandle<Element>  target;
     private MemberSearchResult lastResult;
 
-    public FieldValidator(JavaSource theSource, TypeMirrorHandle fieldTypeHandle) {
+    public FieldValidator(JavaSource theSource, TypeMirrorHandle fieldTypeHandle, TreePathHandle srcHandle) {
         this.theSource = theSource;
         this.fieldTypeHandle = fieldTypeHandle;
+        this.srcHandle = srcHandle;
     }
     
     MemberSearchResult getLastResult() {
@@ -89,42 +96,131 @@ public SearchImpl(TreePathHandle targetHandle, String name) {
         public void run(CompilationController parameter) throws Exception {
             parameter.toPhase(JavaSource.Phase.RESOLVED);
             this.cinfo = parameter;
-            if (targetHandle == null) {
+            if (targetHandle == null || srcHandle == null) {
+                return;
+            }
+            TreePath srcPath = srcHandle.resolve(cinfo);
+            if (srcPath == null) {
                 return;
             }
             TreePath targetPath = targetHandle.resolve(cinfo);
-            if (target == null) {
+            if (targetPath == null) {
                 return;
             }
-            initialScope = cinfo.getTrees().getScope(targetPath);
-
+            initialScope = cinfo.getTrees().getScope(srcPath);
+            Scope targetScope = cinfo.getTrees().getScope(targetPath);
             Map<? extends Element, Scope> visibleVariables = 
                     cinfo.getElementUtilities().findElementsAndOrigins(initialScope, this);
-
+            lastResult = null;
+            Element target = cinfo.getTrees().getElement(targetPath);
             for (Element e : visibleVariables.keySet()) {
-                if (e.getKind() == ElementKind.FIELD ||
-                    e.getKind() == ElementKind.ENUM_CONSTANT) {
-                    Scope def = visibleVariables.get(e);
-                    TypeElement owner = def.getEnclosingClass();
-                    if (owner == null) {
-                        // static import
-                        lastResult = new MemberSearchResult(ElementHandle.create(e),
-                            ElementHandle.create((TypeElement)e.getEnclosingElement()));
-                    } else if (owner == e.getEnclosingElement()) {
-                        lastResult = new MemberSearchResult(ElementHandle.create(e),
-                            ElementHandle.create(owner));
-                    } else {
-                        // special case - hiding superclass field
-                        lastResult = new MemberSearchResult(ElementHandle.create(e),
-                            ElementHandle.create(owner), null);
+                switch (e.getKind()) {
+                    case FIELD: case ENUM_CONSTANT: case PARAMETER:
+                        Scope def = visibleVariables.get(e);
+                        if (def != targetScope) {
+                            for (Scope s = def; s.getEnclosingClass() != null; s = s.getEnclosingScope()) {
+                                if (s == target) {
+                                    lastResult = new MemberSearchResult(ElementHandle.create(e));
+                                    return;
+                                }
+                            }
+                        }
+                        TypeElement owner = def.getEnclosingClass();
+                        if (owner == null) {
+                            // static import
+                            lastResult = new MemberSearchResult(ElementHandle.create(e),
+                                ElementHandle.create((TypeElement)e.getEnclosingElement()));
+                        } else if (owner == e.getEnclosingElement()) {
+                            if (owner == target) {
+                                lastResult = new MemberSearchResult(ElementHandle.create(e));
+                                return;
+                            } else {
+                                lastResult = new MemberSearchResult(ElementHandle.create(e),
+                                    ElementHandle.create(owner));
+                            }
+                        } else {
+                            // special case - hiding superclass field
+                            lastResult = new MemberSearchResult(ElementHandle.create(e),
+                                ElementHandle.create(owner), null);
+                        }
+                        break;
+                    case EXCEPTION_PARAMETER:
+                    case LOCAL_VARIABLE: 
+                    case RESOURCE_VARIABLE: {
+                        TreePath locPath = findLocalPathWorkaround(cinfo, e, srcPath);
+                        if (locPath == null) {
+                            lastResult = new MemberSearchResult(e.getKind());
+                        } else {
+                            lastResult = new MemberSearchResult(TreePathHandle.create(locPath, cinfo), e.getKind());
+                        }
+                    }
+                        return;
+                    default:
+                        // another namespace
+                        return;
+                }
+            }
+        }
+        
+        private TreePath findLocalPathWorkaround(CompilationInfo cinfo, Element e, TreePath srcPath) {
+            TreePath p = cinfo.getTrees().getPath(e);
+            if (p != null) {
+                return p;
+            }
+            switch (e.getKind()) {
+                case LOCAL_VARIABLE:
+                case EXCEPTION_PARAMETER:
+                case RESOURCE_VARIABLE:
+                    break;
+                default:
+                    return null;
+            }
+            while (srcPath != null) {
+                Tree t = srcPath.getLeaf();
+                switch (t.getKind()) {
+                    case METHOD:
+                    case CLASS:
+                        return null;
+                    case VARIABLE:
+                        if (e.getSimpleName().contentEquals(((VariableTree)t).getName())) {
+                            return srcPath;
+                        }
+                        break;
+                    case BLOCK: {
+                        for (Tree x : ((BlockTree)t).getStatements()) {
+                            if (x.getKind() == Tree.Kind.VARIABLE) {
+                                if (e.getSimpleName().contentEquals(((VariableTree)x).getName())) {
+                                    return srcPath;
+                                }
+                            }
+                        }
+                        break;
+                    }
+                    case TRY: {
+                        TryTree tt = (TryTree)t;
+                        if (tt.getResources() != null) {
+                            for (Tree x : tt.getResources()) {
+                                if (x.getKind() == Tree.Kind.VARIABLE) {
+                                    if (e.getSimpleName().contentEquals(((VariableTree)x).getName())) {
+                                        return srcPath;
+                                    }
+                                }
+                            }
+                        }
+                        break;
+                    }
+                    case CATCH: {
+                        CatchTree ct = (CatchTree)t;
+                        if (ct.getParameter() != null && ct.getParameter().getName().contentEquals(e.getSimpleName())) {
+                            return srcPath;
+                        }
+                        break;
                     }
-                } else {
-                    // some locals, report a conflict since the hidden local
-                    // cannot be dereferenced 
-                    lastResult = new MemberSearchResult(ElementHandle.create(e));
-                    return;
+                        
                 }
+                srcPath = srcPath.getParentPath();
             }
+            return null;
         }
 
         @Override
diff --git a/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceFieldFix.java b/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceFieldFix.java
index 7d1efe4ac..86bdcf52d 100644
--- a/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceFieldFix.java
+++ b/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceFieldFix.java
@@ -141,7 +141,7 @@ public ChangeInfo implement() throws IOException, BadLocationException {
         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);
+        FieldValidator fv = new FieldValidator(js, null, this.handle);
         if (targetIsInterface) {
             panel.setAllowAccess(false);
         }
diff --git a/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceFieldPanel.java b/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceFieldPanel.java
index a0ae5223f..97334ed5b 100644
--- a/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceFieldPanel.java
+++ b/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceFieldPanel.java
@@ -161,6 +161,7 @@ public IntroduceFieldPanel(String name, int[] allowInitMethods, int numOccurrenc
         }
         
         changeSupport = new FieldNameSupport();
+        changeSupport.setChangeListener(this);
         resetAccess();
         resetInit();
         adjustInitializeIn();
@@ -200,12 +201,13 @@ protected boolean updateUI(MemberSearchResult result) {
             boolean refactor = false;
             if (result == null) {
                 ok = true;
-            } else if (result.getConflicting() != null) {
-                if (result.getConflicting().getKind() != ElementKind.FIELD) {
+            } else if (result.getConflictingKind() != null) {
+                if (result.getConflictingKind() != ElementKind.FIELD) {
                     notifier.setErrorMessage(Bundle.ERR_LocalVarOrParameterHidden());
                 } else {
                     notifier.setErrorMessage(Bundle.ERR_ConflictingField());
                 }
+                ok = false;
             } else if (result.getOverriden() != null) {
                 // fields are not really overriden, but introducing a field which shadows
                 // a superclass may affect outside code.
@@ -226,7 +228,7 @@ protected boolean updateUI(MemberSearchResult result) {
                 checkRefactorExisting.setEnabled(false);
                 checkRefactorExisting.setSelected(false);
             }
-            return true;
+            return result == null || !result.isConflicting();
         }
 
         @Override
diff --git a/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceMethodFix.java b/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceMethodFix.java
index ed4fc5ff5..c36a4c178 100644
--- a/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceMethodFix.java
+++ b/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceMethodFix.java
@@ -124,7 +124,7 @@ static Fix computeIntroduceMethod(CompilationInfo info, int start, int end, Map<
             return null;
         }
         TreePath block = h.resolve(info);
-        TreePath method = TreeUtils.findMethod(block);
+        TreePath method = TreeUtils.findMethod(block, true);
         if (method == null) {
             errorMessage.put(IntroduceKind.CREATE_METHOD, "ERR_Invalid_Selection");
             return null;
diff --git a/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceMethodPanel.java b/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceMethodPanel.java
index c8704e9ed..94b5dbc96 100644
--- a/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceMethodPanel.java
+++ b/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceMethodPanel.java
@@ -142,7 +142,7 @@ protected boolean updateUI(MemberSearchResult result) {
                 notifier.clearMessages();
                 return true;
             }
-            if (result.getConflicting() != null) {
+            if (result.isConflicting()) {
                 notifier.setErrorMessage(Bundle.ERR_MethodExistsOrConflict());
             } else if (result.getRequiredModifier() != null) {
                 notifier.setWarningMessage(Bundle.WARN_OverridesRestrictedAccess());
@@ -151,7 +151,7 @@ protected boolean updateUI(MemberSearchResult result) {
             } else {
                 notifier.clearMessages();
             }
-            return result.getConflicting() == null;
+            return !result.isConflicting();
         }
     }
     
diff --git a/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceVariableFix.java b/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceVariableFix.java
index c1ceee9e4..6df4f0040 100644
--- a/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceVariableFix.java
+++ b/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceVariableFix.java
@@ -133,7 +133,7 @@ public ChangeInfo implement() throws IOException, BadLocationException {
                 "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);
+        FieldValidator val = new FieldValidator(js, null, this.handle);
         panel.setNotifier(dd.createNotificationLineSupport());
         panel.setValidator(val);
         panel.setTarget(targetHandle);
diff --git a/java.hints/src/org/netbeans/modules/java/hints/introduce/MemberSearchResult.java b/java.hints/src/org/netbeans/modules/java/hints/introduce/MemberSearchResult.java
index 2f79a47ca..d82ede9ca 100644
--- a/java.hints/src/org/netbeans/modules/java/hints/introduce/MemberSearchResult.java
+++ b/java.hints/src/org/netbeans/modules/java/hints/introduce/MemberSearchResult.java
@@ -19,9 +19,12 @@
 package org.netbeans.modules.java.hints.introduce;
 
 import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
 import javax.lang.model.element.Modifier;
 import javax.lang.model.element.TypeElement;
+import org.netbeans.api.java.source.CompilationInfo;
 import org.netbeans.api.java.source.ElementHandle;
+import org.netbeans.api.java.source.TreePathHandle;
 
 /**
  *
@@ -51,6 +54,10 @@
      * to indicate package-level access.
      */
     private final Modifier requiredModifier;
+    
+    private final TreePathHandle conflictingPath;
+    
+    private final ElementKind kind;
 
     public MemberSearchResult(ElementHandle<? extends Element> conflicting) {
         this.conflicting = conflicting;
@@ -58,6 +65,28 @@ public MemberSearchResult(ElementHandle<? extends Element> conflicting) {
         this.shadowedGate = null;
         this.gateSuper = false;
         this.requiredModifier = null;
+        this.conflictingPath = null;
+        this.kind = conflicting.getKind();
+    }
+    
+    public MemberSearchResult(ElementKind kind) {
+        this.conflicting = null;
+        this.shadowed = null;
+        this.shadowedGate = null;
+        this.gateSuper = false;
+        this.requiredModifier = null;
+        this.conflictingPath = null;
+        this.kind = kind;
+    }
+
+    public MemberSearchResult(TreePathHandle conflicting, ElementKind kind) {
+        this.conflicting = null;
+        this.shadowed = null;
+        this.shadowedGate = null;
+        this.gateSuper = false;
+        this.requiredModifier = null;
+        this.conflictingPath = conflicting;
+        this.kind = kind;
     }
 
     public MemberSearchResult(ElementHandle<? extends Element> shadowed, ElementHandle<? extends TypeElement> shadowedGate) {
@@ -66,6 +95,8 @@ public MemberSearchResult(ElementHandle<? extends Element> shadowed, ElementHand
         this.gateSuper = false;
         this.conflicting = null;
         this.requiredModifier = null;
+        this.conflictingPath = null;
+        this.kind = null;
     }
 
     public MemberSearchResult(ElementHandle<? extends Element> shadowed, ElementHandle<? extends TypeElement> shadowedGate, Modifier requiredModifier) {
@@ -74,6 +105,8 @@ public MemberSearchResult(ElementHandle<? extends Element> shadowed, ElementHand
         this.requiredModifier = requiredModifier;
         this.gateSuper = true;
         this.conflicting = null;
+        this.conflictingPath = null;
+        this.kind = null;
     }
     
     public ElementHandle<? extends Element> getOverriden() {
@@ -84,6 +117,27 @@ public MemberSearchResult(ElementHandle<? extends Element> shadowed, ElementHand
         return conflicting;
     }
 
+    public TreePathHandle getConflictingPath() {
+        return conflictingPath;
+    }
+    
+    public ElementKind getConflictingKind() {
+        return kind;
+    }
+    
+    public Element resolveConflict(CompilationInfo info) {
+        if (conflicting != null) {
+            return conflicting.resolve(info);
+        } else if (conflictingPath != null) {
+            return conflictingPath.resolveElement(info);
+        }
+        return null;
+    }
+    
+    public boolean isConflicting() {
+        return conflicting != null || conflictingPath != null;
+    }
+
     public ElementHandle<? extends Element> getShadowed() {
         return requiredModifier == null ? shadowed : null;
     }
diff --git a/java.hints/src/org/netbeans/modules/java/hints/introduce/TreeUtils.java b/java.hints/src/org/netbeans/modules/java/hints/introduce/TreeUtils.java
index 1a2dc4aa4..9215c012b 100644
--- a/java.hints/src/org/netbeans/modules/java/hints/introduce/TreeUtils.java
+++ b/java.hints/src/org/netbeans/modules/java/hints/introduce/TreeUtils.java
@@ -178,6 +178,10 @@ static TreePath findBlockOrStatement(TreePath statementPath, boolean statement)
      * @return path to the nearest enclosing executable or {@code null} in case of error.
      */
     static TreePath findMethod(TreePath path) {
+        return findMethod(path, false);
+    }
+    
+    static TreePath findMethod(TreePath path, boolean methodOnly) {
         while (path != null) {
             Tree leaf = path.getLeaf();
             switch (leaf.getKind()) {
@@ -186,8 +190,11 @@ static TreePath findMethod(TreePath path) {
                         return path;
                     }
                     break;
-                case METHOD:
                 case LAMBDA_EXPRESSION:
+                    if (methodOnly) {
+                        break;
+                    }
+                case METHOD:
                     return path;
                 default:
                     break;
diff --git a/java.hints/src/org/netbeans/modules/java/hints/suggestions/TooStrongCast.java b/java.hints/src/org/netbeans/modules/java/hints/suggestions/TooStrongCast.java
index bc70ff8bd..c5ec714ab 100644
--- a/java.hints/src/org/netbeans/modules/java/hints/suggestions/TooStrongCast.java
+++ b/java.hints/src/org/netbeans/modules/java/hints/suggestions/TooStrongCast.java
@@ -124,7 +124,7 @@ public static ErrorDescription broadTypeCast(HintContext ctx) {
             return null;
         }
         
-        if (!Utilities.isValidType(casteeType)) {
+        if (!Utilities.isValidValueType(casteeType)) {
             return null;
         }
 
@@ -144,14 +144,14 @@ public static ErrorDescription broadTypeCast(HintContext ctx) {
         String lst = null;
         List<TypeMirror> filteredTypes = new ArrayList<TypeMirror>(types.size());
         TypeMirror castType = info.getTrees().getTypeMirror(new TreePath(ctx.getPath(), tct.getType()));
-        if (!Utilities.isValidType(castType)) {
+        if (!Utilities.isValidValueType(castType)) {
             return null;
         }
         TypeMirror castErasure = info.getTypes().erasure(castType);
         CharSequence currentTypeName = info.getTypeUtilities().getTypeName(castType);
         for (Iterator<? extends TypeMirror> it = types.iterator(); it.hasNext(); ) {
             TypeMirror tm = it.next();
-            if (!Utilities.isValidType(tm)) {
+            if (!Utilities.isValidValueType(tm)) {
                 continue;
             }
             if (tm.getKind() == TypeKind.TYPEVAR) {
diff --git a/java.j2semodule/src/org/netbeans/modules/java/j2semodule/resources/build-impl.xsl b/java.j2semodule/src/org/netbeans/modules/java/j2semodule/resources/build-impl.xsl
index ca1a9cc28..4025cdb6f 100644
--- a/java.j2semodule/src/org/netbeans/modules/java/j2semodule/resources/build-impl.xsl
+++ b/java.j2semodule/src/org/netbeans/modules/java/j2semodule/resources/build-impl.xsl
@@ -2261,7 +2261,7 @@ is divided into following sections:
                 <pathconvert refid="run.test.packages.internal" property="run.test.addexports.internal" pathsep=" ">
                     <chainedmapper>
                         <filtermapper>
-                            <replacestring from="${{build.test.modules.dir.abs.internal}}/" to=""/>
+                            <replacestring from="${{build.test.modules.dir.abs.internal}}${{file.separator}}" to=""/>
                         </filtermapper>
                         <regexpmapper from="^([^${{file.separator.string}}]*)\Q${{file.separator}}\E(.*)\Q${{file.separator}}\E.*\.class$$" to="\1${{path.separator}}\2"/>
                         <filtermapper>
diff --git a/java.source.base/src/org/netbeans/modules/java/source/pretty/VeryPretty.java b/java.source.base/src/org/netbeans/modules/java/source/pretty/VeryPretty.java
index 5b23f724b..d006e5128 100644
--- a/java.source.base/src/org/netbeans/modules/java/source/pretty/VeryPretty.java
+++ b/java.source.base/src/org/netbeans/modules/java/source/pretty/VeryPretty.java
@@ -906,11 +906,6 @@ public void visitClassDef(JCClassDecl tree) {
 	if (!members.isEmpty()) {
 	    blankLines(enclClass.name.isEmpty() ? cs.getBlankLinesAfterAnonymousClassHeader() : (flags & ENUM) != 0 ? cs.getBlankLinesAfterEnumHeader() : cs.getBlankLinesAfterClassHeader());
             boolean firstMember = true;
-            if ((tree.mods.flags & ENUM) != 0 && members.get(0) instanceof FieldGroupTree && ((FieldGroupTree) members.get(0)).isEnum()) {
-                printEnumConstants(((FieldGroupTree) members.get(0)).getVariables(), false, false);
-                firstMember = false;
-                members.remove(0);
-            }
             for (JCTree t : members) {
                 printStat(t, true, firstMember, true, true, false);
                 firstMember = false;
@@ -955,8 +950,9 @@ private void printEnumConstants(java.util.List<? extends JCTree> defs, boolean f
                     }
                 }
                 printStat(c, true, false, col, false, printComments);
-            } else if (!isSynthetic(c))
+            } else if (!isSynthetic(c)) {
                 hasNonEnumerator = true;
+            }
         }
         if (hasNonEnumerator || forceSemicolon) {
             print(";");
diff --git a/javafx2.editor/src/org/netbeans/modules/javafx2/editor/fxml/FXMLEditAction.java b/javafx2.editor/src/org/netbeans/modules/javafx2/editor/fxml/FXMLEditAction.java
index 00296dc19..2743e5ed2 100644
--- a/javafx2.editor/src/org/netbeans/modules/javafx2/editor/fxml/FXMLEditAction.java
+++ b/javafx2.editor/src/org/netbeans/modules/javafx2/editor/fxml/FXMLEditAction.java
@@ -57,9 +57,6 @@ public FXMLEditAction(Lookup context) {
     }
     
     void init() {
-        assert SwingUtilities.isEventDispatchThread() 
-               : "this shall be called just from AWT thread"; // NOI18N
- 
         if (lkpInfo != null) {
             return;
         }
diff --git a/javafx2.editor/src/org/netbeans/modules/javafx2/editor/fxml/FXMLOpenAction.java b/javafx2.editor/src/org/netbeans/modules/javafx2/editor/fxml/FXMLOpenAction.java
index 8c849b085..ff845ee4b 100644
--- a/javafx2.editor/src/org/netbeans/modules/javafx2/editor/fxml/FXMLOpenAction.java
+++ b/javafx2.editor/src/org/netbeans/modules/javafx2/editor/fxml/FXMLOpenAction.java
@@ -81,9 +81,6 @@ private void setupOpener() {
     }
     
     void init() {
-        assert SwingUtilities.isEventDispatchThread() 
-               : "this shall be called just from AWT thread"; // NOI18N
- 
         if (lkpInfo != null) {
             return;
         }
diff --git a/jshell.support/src/org/netbeans/modules/jshell/editor/CompletionFilter.java b/jshell.support/src/org/netbeans/modules/jshell/editor/CompletionFilter.java
index 3f366dadb..b212282f0 100644
--- a/jshell.support/src/org/netbeans/modules/jshell/editor/CompletionFilter.java
+++ b/jshell.support/src/org/netbeans/modules/jshell/editor/CompletionFilter.java
@@ -39,6 +39,7 @@
 import javax.lang.model.element.AnnotationValue;
 import javax.lang.model.element.Element;
 import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.NestingKind;
 import javax.lang.model.element.PackageElement;
 import javax.lang.model.element.TypeElement;
 import javax.lang.model.type.DeclaredType;
@@ -216,7 +217,7 @@ public boolean isAccessible(Scope scope, TypeElement te) {
         if (te == null || scope == null) {
             return false;
         }
-        if (te.getQualifiedName().toString().startsWith("REPL.")) {
+        if (te.getQualifiedName().toString().startsWith("REPL.") && te.getNestingKind() == NestingKind.TOP_LEVEL) {
             return false;
         }
         return delegate.isAccessible(scope, te);
diff --git a/jshell.support/src/org/netbeans/modules/jshell/env/JShellEnvironment.java b/jshell.support/src/org/netbeans/modules/jshell/env/JShellEnvironment.java
index ccff680f5..f367093cc 100644
--- a/jshell.support/src/org/netbeans/modules/jshell/env/JShellEnvironment.java
+++ b/jshell.support/src/org/netbeans/modules/jshell/env/JShellEnvironment.java
@@ -117,6 +117,8 @@
     
     private final ShellL            shellL = new ShellL();
     
+    private Document document;
+    
     protected JShellEnvironment(Project project, String displayName) {
         this.project = project;
         this.displayName = displayName;
@@ -397,6 +399,7 @@ public synchronized void start() throws IOException {
         }
         this.classpathInfo = cpi;
         forceOpenDocument();
+        // createSession will get opened document, shutdown runs under lock
         doStartAndFire(ShellSession.createSession(this));
     }
 
@@ -454,8 +457,10 @@ private void fireExecuting(ShellSession session, boolean start) {
     }
     
     private void doStartAndFire(ShellSession nss) {
-        this.shellSession = nss;
-        starting = true;
+        synchronized (this) {
+            this.shellSession = nss;
+            starting = true;
+        }
         Pair<ShellSession, Task> res = nss.start();
         nss.getModel().addConsoleListener(new ConsoleListener() {
             @Override
@@ -481,8 +486,15 @@ public void closed(ConsoleEvent e) {}
         fireShellStatus(event);
         
         res.second().addTaskListener(e -> {
-            starting = false;
-            fireShellStarted(event);
+            synchronized (this) {
+                starting = false;
+                if (shellSession != nss) {
+                    return;
+                }
+            }
+            if (nss.isValid() && nss.isActive()) {
+                fireShellStarted(event);
+            }
             fireShellStatus(event);
         });
         
@@ -526,12 +538,18 @@ public FileObject getConsoleFile() {
     
     private Document forceOpenDocument() throws IOException {
         EditorCookie cake = consoleFile.getLookup().lookup(EditorCookie.class);
-        return cake == null ? null : cake.openDocument();
+        if (cake == null) {
+            return null;
+        }
+        Document d =  cake.openDocument();
+        synchronized (this) {
+            this.document = d;
+        }
+        return d;
     }
 
-    public Document getConsoleDocument() {
-        EditorCookie cake = consoleFile.getLookup().lookup(EditorCookie.class);
-        return cake == null ? null : cake.getDocument();
+    public synchronized Document getConsoleDocument() {
+        return document;
     }
     
     public ClassPath getSnippetClassPath() {
@@ -576,8 +594,6 @@ private void postCloseCleanup() {
         ShellRegistry.get().closed(this);
     }
     
-    private Document document;
-    
     public void open() throws IOException {
         assert workRoot != null;
         DataObject d = DataObject.find(getConsoleFile());
@@ -586,7 +602,6 @@ public void open() throws IOException {
         if (shellSession == null) {
             start();
             cake.open();
-            document = cake.openDocument();
         } else {
             cake.open();
             document = cake.openDocument();
diff --git a/jshell.support/src/org/netbeans/modules/jshell/j2se/JShellStartupExtender.java b/jshell.support/src/org/netbeans/modules/jshell/j2se/JShellStartupExtender.java
index 0fbcdc73e..4c8a384aa 100644
--- a/jshell.support/src/org/netbeans/modules/jshell/j2se/JShellStartupExtender.java
+++ b/jshell.support/src/org/netbeans/modules/jshell/j2se/JShellStartupExtender.java
@@ -78,7 +78,9 @@
         
         J2SEPropertyEvaluator  prjEval = p.getLookup().lookup(J2SEPropertyEvaluator.class);
         JavaPlatform platform = ShellProjectUtils.findPlatform(p);
-        List<String> args = ShellLaunchManager.buildLocalJVMAgentArgs(platform, agent, prjEval.evaluator()::getProperty);
+        List<String> args = ShellProjectUtils.quoteCmdArgs(
+                ShellLaunchManager.buildLocalJVMAgentArgs(platform, agent, prjEval.evaluator()::getProperty)
+        );
         LOG.log(Level.FINE, "Final args: {0}", args);
         
         List<String> shellArgs = ShellProjectUtils.launchVMOptions(p);
diff --git a/jshell.support/src/org/netbeans/modules/jshell/launch/ShellLaunchManager.java b/jshell.support/src/org/netbeans/modules/jshell/launch/ShellLaunchManager.java
index 40c7350d8..dd58403d9 100644
--- a/jshell.support/src/org/netbeans/modules/jshell/launch/ShellLaunchManager.java
+++ b/jshell.support/src/org/netbeans/modules/jshell/launch/ShellLaunchManager.java
@@ -533,7 +533,7 @@ public static String getAuthKey(String args) {
                 ShellProjectUtils.isModularJDK(platform) ?
                     "modules/ext/nb-mod-jshell-probe.jar": 
                     "modules/ext/nb-custom-jshell-probe.jar",
-                "org.netbeans.modules.jshell.support", false);
+                "org.netbeans.lib.jshell.agent", false);
         String policy = propertyEvaluator.apply(PropertyNames.JSHELL_CLASS_LOADING);
         if (policy == null) {
             policy = RunOptionsModel.LoaderPolicy.SYSTEM.toString().toLowerCase();
diff --git a/jshell.support/src/org/netbeans/modules/jshell/maven/MavenShellLauncher.java b/jshell.support/src/org/netbeans/modules/jshell/maven/MavenShellLauncher.java
index 6817ec187..ce33c09a0 100644
--- a/jshell.support/src/org/netbeans/modules/jshell/maven/MavenShellLauncher.java
+++ b/jshell.support/src/org/netbeans/modules/jshell/maven/MavenShellLauncher.java
@@ -101,6 +101,11 @@ public boolean checkRunConfig(RunConfig config, ExecutionContext con) {
                 agent, 
                 config.getProperties()::get
         );
+        String agentString = args.get(args.size() -1);
+        List<String> vmArgs = ShellProjectUtils.launchVMOptions(project);
+        if (vmArgs != null) {
+            args.addAll(vmArgs);
+        }
         String execArgs = config.getProperties().get(PROPERTY_EXEC_ARGS);
         if (execArgs != null) {
             StringBuilder sb = new StringBuilder();
@@ -108,7 +113,7 @@ public boolean checkRunConfig(RunConfig config, ExecutionContext con) {
                 if (sb.length() > 0) {
                     sb.append(" "); // NOI18N
                 }
-                sb.append(a);
+                sb.append(ShellProjectUtils.quoteCmdArg(a));
             }
             String newArgs;
 
@@ -119,7 +124,7 @@ public boolean checkRunConfig(RunConfig config, ExecutionContext con) {
             }
             config.setProperty(PROPERTY_EXEC_ARGS, newArgs);
         }        
-        config.setProperty(PROPERTY_JSHELL_AGENT, args.get(args.size() -1));
+        config.setProperty(PROPERTY_JSHELL_AGENT, agentString);
         config.setProperty(PROPERTY_JSHELL_KEY, agent.getAuthorizationKey());
         return true;
     }
diff --git a/jshell.support/src/org/netbeans/modules/jshell/navigation/SnippetNodes.java b/jshell.support/src/org/netbeans/modules/jshell/navigation/SnippetNodes.java
index abf476584..cec617d75 100644
--- a/jshell.support/src/org/netbeans/modules/jshell/navigation/SnippetNodes.java
+++ b/jshell.support/src/org/netbeans/modules/jshell/navigation/SnippetNodes.java
@@ -232,9 +232,12 @@ private synchronized void attachTo(JShell shell) {
             state = null;
         }
         if (shell != null) {
+            NR subscription = new NR(this, shell);
+            subscription.subscribe();
+            // may fail in JShell, record in member variables only after successful
+            // registration
             state = shell;
-            sub = new NR(this, shell);
-            sub.subscribe();
+            sub = subscription;
         }
     }
 
@@ -247,7 +250,11 @@ public void shellStarted(ShellEvent ev) {
             }
         }
         update();
-        attachTo(ev.getEngine());
+        try {
+            attachTo(ev.getEngine());
+        } catch (IllegalStateException ex) {
+            // the shell may have terminated in between the event was generated and now. Ignore.
+        }
         refreshNodeNames();
     }
 
diff --git a/jshell.support/src/org/netbeans/modules/jshell/parsing/JShellLexer.java b/jshell.support/src/org/netbeans/modules/jshell/parsing/JShellLexer.java
index 7ea2eefe4..3d3bc2d13 100644
--- a/jshell.support/src/org/netbeans/modules/jshell/parsing/JShellLexer.java
+++ b/jshell.support/src/org/netbeans/modules/jshell/parsing/JShellLexer.java
@@ -50,16 +50,17 @@
         "exit", "reset", "reload",
         
         "classpath", "history",
-            
+        "debug",
+        
         "help",
+        "set",
         "?", "!"
     };
     
     private static final String[] COMMAND_STRINGS = {
         "l", "list", // NOI18N
-        "", "seteditor", // NOI18N
-        "d", "drop", // NOI18N
-        "s", "save", // NOI18N
+        "dr", "drop", // NOI18N
+        "sa", "save", // NOI18N
         "o", "open", // NOI18N
         "v", "vars", // NOI18N
         "m", "methods",  // NOI18N
@@ -70,7 +71,9 @@
         "rel", "reload",  // NOI18N
         "c", "classpath",  // NOI18N
         "hi", "history",  // NOI18N
+        "de", "debug",    // NOI18N
         "he", "?", "help",  // NOI18N
+        "se", "set",        // NOI18N
         "!", "" // NOI18N
     };
     
@@ -523,9 +526,6 @@ private int startsCommand(String s) {
             verbatim = false;
             c = input.read();
         }
-        if (c == '\n') { // NOI18N
-            state = S.INITIAL;
-        }
         return tokenFactory.createToken(tokenId, input.readLength());
     }
 
diff --git a/jshell.support/src/org/netbeans/modules/jshell/parsing/SnippetRegistry.java b/jshell.support/src/org/netbeans/modules/jshell/parsing/SnippetRegistry.java
index f0f6319eb..ef4578a52 100644
--- a/jshell.support/src/org/netbeans/modules/jshell/parsing/SnippetRegistry.java
+++ b/jshell.support/src/org/netbeans/modules/jshell/parsing/SnippetRegistry.java
@@ -453,8 +453,10 @@ private FileObject createSnippetFile(SnippetHandle info, String resName) {
                     ows.flush();
                 }
                 FileObject ret = pkg.getFileObject(fn);
-                synchronized (this) {
-                    snippetTimeStamps.put(snip, ret.lastModified().getTime());
+                if (snip != null) {
+                    synchronized (this) {
+                        snippetTimeStamps.put(snip, ret.lastModified().getTime());
+                    }
                 }
                 ModelAccessor.INSTANCE.setFile(info, ret);
                 return finalize(info, ret);
diff --git a/jshell.support/src/org/netbeans/modules/jshell/project/REPLAction2.java b/jshell.support/src/org/netbeans/modules/jshell/project/REPLAction2.java
index c18b2bd9a..65b526ed8 100644
--- a/jshell.support/src/org/netbeans/modules/jshell/project/REPLAction2.java
+++ b/jshell.support/src/org/netbeans/modules/jshell/project/REPLAction2.java
@@ -73,6 +73,11 @@ public boolean enable(Project project) {
     @Override
     public void perform(Project project) {
         ActionProvider p = project.getLookup().lookup(ActionProvider.class);
+        // check whether the is CoS enabled fo the project
+        if (ShellProjectUtils.isCompileOnSave(project)) {
+            doRunShell(project);
+            return;
+        }
         if (p == null || !p.isActionEnabled(ActionProvider.COMMAND_BUILD, Lookups.singleton(project))) {
             StatusDisplayer.getDefault().setStatusText(Bundle.ERR_CannotBuildProject());
             return;
diff --git a/jshell.support/src/org/netbeans/modules/jshell/project/ShellProjectUtils.java b/jshell.support/src/org/netbeans/modules/jshell/project/ShellProjectUtils.java
index b3bfe02fa..e8a508107 100644
--- a/jshell.support/src/org/netbeans/modules/jshell/project/ShellProjectUtils.java
+++ b/jshell.support/src/org/netbeans/modules/jshell/project/ShellProjectUtils.java
@@ -35,6 +35,7 @@
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Properties;
 import java.util.Set;
 import javax.lang.model.element.ModuleElement;
 import javax.lang.model.element.ModuleElement.DirectiveKind;
@@ -60,15 +61,18 @@
 import org.netbeans.api.project.ProjectUtils;
 import org.netbeans.api.project.SourceGroup;
 import org.netbeans.api.project.Sources;
+import org.netbeans.modules.java.api.common.project.ProjectProperties;
 import org.netbeans.modules.java.j2seproject.api.J2SEPropertyEvaluator;
 import org.netbeans.modules.java.source.parsing.FileObjects;
 import org.netbeans.modules.jshell.launch.PropertyNames;
+import org.netbeans.modules.maven.api.execute.RunUtils;
 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;
 import org.netbeans.spi.java.classpath.support.ClassPathSupport;
+import org.netbeans.spi.project.AuxiliaryProperties;
 import org.openide.filesystems.FileObject;
 import org.openide.filesystems.FileUtil;
 import org.openide.filesystems.URLMapper;
@@ -184,6 +188,10 @@ public static JavaPlatform findPlatform(ClassPath bootCP) {
         
         for (SourceGroup sg : org.netbeans.api.project.ProjectUtils.getSources(project).getSourceGroups(JavaProjectConstants.SOURCES_TYPE_JAVA)) {
             if (isNormalRoot(sg)) {
+                FileObject fo = sg.getRootFolder().getFileObject("module-info.java");
+                if (fo == null) {
+                    continue;
+                }
                 URL u = URLMapper.findURL(sg.getRootFolder(), URLMapper.INTERNAL);
                 BinaryForSourceQuery.Result r = BinaryForSourceQuery.findBinaryRoots(u);
                 for (URL u2 : r.getRoots()) {
@@ -252,6 +260,10 @@ public static JavaPlatform findPlatform(ClassPath bootCP) {
     }
     
     public static boolean isModularProject(Project project) {
+        return isModularProject(project, false);
+    }
+    
+    public static boolean isModularProject(Project project, boolean checkModuleInfo) {
         if (project == null) { 
             return false;
         }
@@ -263,6 +275,9 @@ public static boolean isModularProject(Project project) {
         if (!(s != null && new SpecificationVersion("9").compareTo(new SpecificationVersion(s)) <= 0)) {
             return false;
         }
+        if (!checkModuleInfo) {
+            return true;
+        }
         // find module-info.java
         for (SourceGroup sg : ProjectUtils.getSources(project).getSourceGroups(JavaProjectConstants.SOURCES_TYPE_JAVA)) {
             if (isNormalRoot(sg)) {
@@ -331,8 +346,7 @@ public static ClassPath projecRuntimeClassPath(Project project) {
                 ShellProjectUtils.findProjectImportedModules(project, 
                     ShellProjectUtils.findProjectModules(project, null))
         );
-        ShellProjectUtils.findProjectModules(project, null);
-        boolean modular = isModularJDK(findPlatform(project));
+        boolean modular = isModularProject(project, false);
         if (exportMods.isEmpty() || !modular) {
             return null;
         }
@@ -358,16 +372,17 @@ public static ClassPath projecRuntimeClassPath(Project project) {
                 ShellProjectUtils.findProjectImportedModules(project, 
                     ShellProjectUtils.findProjectModules(project, null))
         );
-        ShellProjectUtils.findProjectModules(project, null);
-        boolean modular = isModularJDK(findPlatform(project));
+        boolean modular = isModularProject(project, false);
         if (exportMods.isEmpty() || !modular) {
             return null;
         }
         List<String> addReads = new ArrayList<>();
-        exportMods.add("jdk.jshell");
+        exportMods.add("jdk.jshell"); // NOI18N
         Collections.sort(exportMods);
-        addReads.add("--add-modules " + String.join(",", exportMods));
-        addReads.add("--add-reads jdk.jshell=ALL-UNNAMED"); // NOI18N
+        addReads.add("--add-modules"); // NOI18N
+        addReads.add(String.join(",", exportMods));
+        addReads.add("--add-reads"); // NOI18N
+        addReads.add("jdk.jshell=ALL-UNNAMED"); // NOI18N
         
         // now export everything from the project:
         Map<String, Collection<String>> packages = ShellProjectUtils.findProjectModulesAndPackages(project);
@@ -376,7 +391,8 @@ public static ClassPath projecRuntimeClassPath(Project project) {
             Collection<String> vals = en.getValue();
 
             for (String v : vals) {
-                addReads.add(String.format("--add-exports %s/%s=ALL-UNNAMED", 
+                addReads.add("--add-exports"); // NOI18N
+                addReads.add(String.format("%s/%s=ALL-UNNAMED",  // NOI18N
                         p, v));
             }
         }
@@ -395,6 +411,10 @@ public static FileObject findProjectRoots(Project project, List<URL> urls) {
                     URL u = URLMapper.findURL(sg.getRootFolder(), URLMapper.INTERNAL);
                     BinaryForSourceQuery.Result r = BinaryForSourceQuery.findBinaryRoots(u);
                     for (URL ru : r.getRoots()) {
+                        // ignore JARs, prefer output folder:
+                        if (FileUtil.isArchiveArtifact(ru)) {
+                            continue;
+                        }
                         if (knownURLs.add(ru)) {
                             urls.add(ru);
                         }
@@ -416,4 +436,46 @@ public static JavaPlatform findPlatform(Project project) {
         JavaPlatform platform = findPlatform(ClassPath.getClassPath(ref, ClassPath.BOOT));
         return platform != null ? platform : JavaPlatform.getDefault();
     }
+    
+    /**
+     * Attempts to detect Compile on Save enabled.
+     */
+    public static boolean isCompileOnSave(Project p) {
+        J2SEPropertyEvaluator  prjEval = p.getLookup().lookup(J2SEPropertyEvaluator.class);
+        if (prjEval == null) {
+            // try maven approach
+            return RunUtils.isCompileOnSaveEnabled(p);
+        }
+        String compileOnSaveProperty = prjEval.evaluator().getProperty(ProjectProperties.COMPILE_ON_SAVE);
+        if (compileOnSaveProperty == null || !Boolean.valueOf(compileOnSaveProperty)) {
+            return false;
+        }
+        Map<String, String> props = prjEval.evaluator().getProperties();
+        if (props == null) {
+            return false;
+        }
+        for (Map.Entry<String, String> e : props.entrySet()) {
+            if (e.getKey().startsWith(ProjectProperties.COMPILE_ON_SAVE_UNSUPPORTED_PREFIX)) {
+                if (e.getValue() != null && Boolean.valueOf(e.getValue())) {
+                    return false;
+                }
+            }
+        }                    
+        return true;
+    }
+    
+    public static String quoteCmdArg(String s) {
+        if (s.indexOf(' ') == -1) {
+            return s;
+        }
+        return '"' + s + '"'; // NOI18N
+    }
+    
+    public static List<String> quoteCmdArgs(List<String> args) {
+        List<String> ret = new ArrayList<>();
+        for (String a : args) {
+            ret.add(quoteCmdArg(a));
+        }
+        return ret;
+    }
 }
diff --git a/jshell.support/src/org/netbeans/modules/jshell/support/ShellSession.java b/jshell.support/src/org/netbeans/modules/jshell/support/ShellSession.java
index 8a41dc25e..211b86428 100644
--- a/jshell.support/src/org/netbeans/modules/jshell/support/ShellSession.java
+++ b/jshell.support/src/org/netbeans/modules/jshell/support/ShellSession.java
@@ -614,6 +614,10 @@ public Launcher(ExecutionControlProvider execEnv) throws IOException {
                 execEnv);
         }
 
+        protected List<String>  historyItems() {
+            return ShellSession.this.historyItems().stream().map((i) -> i.getContents()).collect(Collectors.toList());
+        }
+
         @Override
         protected JShell.Builder makeBuilder() {
             return customizeBuilder(super.makeBuilder());
@@ -693,6 +697,8 @@ protected NbExecutionControl execControlCreated(NbExecutionControl ctrl) {
             }
             return super.execControlCreated(ctrl);
         }
+        
+        
     }
     
     private SwitchingJavaFileManger fileman;
@@ -1591,11 +1597,12 @@ public void stopExecutingCode() {
                 public void run(ResultIterator resultIterator) throws Exception {
                     ConsoleContents console = ConsoleContents.get(resultIterator);
                     ConsoleSection input = console.getInputSection();
+                    ConsoleSection exec = console.getSectionModel().getExecutingSection();
                     for (ConsoleSection s : console.getSectionModel().getSections()) {
                         if (!s.getType().input) {
                             continue;
                         }
-                        if (s == input) {
+                        if (s == input || s == exec) {
                             // do not save current input
                             continue;
                         }
diff --git a/jshell.support/src/org/netbeans/modules/jshell/tool/JShellLauncher.java b/jshell.support/src/org/netbeans/modules/jshell/tool/JShellLauncher.java
index 4be07c5bb..7ecdffbda 100644
--- a/jshell.support/src/org/netbeans/modules/jshell/tool/JShellLauncher.java
+++ b/jshell.support/src/org/netbeans/modules/jshell/tool/JShellLauncher.java
@@ -23,6 +23,7 @@
 import java.io.PrintStream;
 import java.io.ByteArrayInputStream;
 import java.util.Collections;
+import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.prefs.Preferences;
@@ -115,6 +116,10 @@ public void evaluate(String command, boolean prompt) throws IOException {
         }
     }
     
+    protected List<String>  historyItems() {
+        return Collections.emptyList();
+    }
+    
     private class IOContextImpl extends IOContext {
         private String  str;
         private String  promptAfter;
@@ -146,7 +151,7 @@ public boolean interactiveOutput() {
 
         @Override
         public Iterable<String> currentSessionHistory() {
-            return Collections.emptyList();
+            return historyItems();
         }
 
         @Override
diff --git a/jshell.support/src/org/netbeans/modules/jshell/tool/JShellTool.java b/jshell.support/src/org/netbeans/modules/jshell/tool/JShellTool.java
index 662355095..901e49049 100644
--- a/jshell.support/src/org/netbeans/modules/jshell/tool/JShellTool.java
+++ b/jshell.support/src/org/netbeans/modules/jshell/tool/JShellTool.java
@@ -785,13 +785,17 @@ protected JShell createJShellInstance() {
     private boolean isRunningInteractive() {
         return currentNameSpace != null && currentNameSpace == mainNamespace;
     }
+    
+    boolean permitSystemSettings = false;
 
     //where -- one-time per run initialization of feedback modes
     private void initFeedback() {
         // No fluff, no prefix, for init failures
         MessageHandler initmh = new InitMessageHandler();
         // Execute the feedback initialization code in the resource file
+        permitSystemSettings = true;
         startUpRun(getResourceString("startup.feedback"));
+        permitSystemSettings = false;
         // These predefined modes are read-only
         feedback.markModesReadOnly();
         // Restore user defined modes retained on previous run with /set mode -retain
@@ -1292,11 +1296,11 @@ private static CompletionProvider orMostSpecificCompletion(
                         "mode", skipWordThenCompletion(orMostSpecificCompletion(
                                 feedback.modeCompletions(SET_MODE_OPTIONS_COMPLETION_PROVIDER),
                                 SET_MODE_OPTIONS_COMPLETION_PROVIDER)),
-                        "prompt", feedback.modeCompletions(),
-                        "editor", fileCompletions(Files::isExecutable),
+//                        "prompt", feedback.modeCompletions(),
+//                        "editor", fileCompletions(Files::isExecutable),
                         "start", FILE_COMPLETION_PROVIDER),
                         STARTSWITH_MATCHER), 
-                CommandKind.HIDDEN));
+                CommandKind.NORMAL));
 
         registerCommand(new Command("/?",
                 "help.quest",
@@ -1389,15 +1393,17 @@ final boolean cmdSet(String arg) {
                 return feedback.setMode(this, at,
                         retained -> prefs.put(MODE_KEY, retained));
             case "prompt":
-                return feedback.setPrompt(this, at);
-            case "editor":
-                return new SetEditor(at).set();
+                if (permitSystemSettings) {
+                    return feedback.setPrompt(this, at);
+                } else {
+                    break;
+                }
             case "start":
                 return setStart(at);
             default:
-                errormsg("jshell.err.arg", cmd, at.val());
-                return false;
         }
+        errormsg("jshell.err.arg", cmd, at.val());
+        return false;
     }
 
     boolean setFeedback(MessageHandler messageHandler, ArgTokenizer at) {
diff --git a/jshell.support/src/org/netbeans/modules/jshell/tool/l10n.properties b/jshell.support/src/org/netbeans/modules/jshell/tool/l10n.properties
index 5a398c2e9..19ad3f780 100644
--- a/jshell.support/src/org/netbeans/modules/jshell/tool/l10n.properties
+++ b/jshell.support/src/org/netbeans/modules/jshell/tool/l10n.properties
@@ -368,7 +368,7 @@ Display information about jshell.\n\
      Display information about the specified help subject. Example: /help intro
 
 help.set.summary = set jshell configuration information
-help.set.args = editor|start|feedback|mode|prompt|truncation|format ...
+help.set.args = start|feedback|mode|truncation|format ...
 help.set =\
 Set jshell configuration information, including:\n\
 the external editor to use, the start-up definitions to use, a new feedback mode,\n\
@@ -394,7 +394,7 @@ the command prompt, the feedback mode to use, or the format of output.\n\
      To show the settings of any of the above, omit the set value.\n\n\
 To get more information about one of these forms, use /help with the form specified.\n\
 For example:   /help /set format
-
+/
 help.quest.summary = get information about jshell
 help.quest.args = [<command>|<subject>]
 help.quest =\
@@ -823,7 +823,7 @@ startup.feedback = \
 /set format normal display '{result}'                                                       added,modified,replaced-expression,varvalue,assignment,varinit,vardecl-ok-primary    \n\
 /set mode concise -quiet normal    \n\
 \n\
-/set prompt concise '[%s-]> '   '[%s]>> '    \n\
+/set prompt concise '[%s]-> '   '[%s]>> '    \n\
 \n\
 /set format concise display ''                                                              class,interface,enum,annotation,method,assignment,varinit,vardecl-ok    \n\
 \n\
diff --git a/openide.filesystems/src/org/openide/filesystems/MemoryFileSystem.java b/openide.filesystems/src/org/openide/filesystems/MemoryFileSystem.java
index 1d09b3a6e..71e0474c2 100644
--- a/openide.filesystems/src/org/openide/filesystems/MemoryFileSystem.java
+++ b/openide.filesystems/src/org/openide/filesystems/MemoryFileSystem.java
@@ -40,6 +40,7 @@
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicLong;
@@ -466,6 +467,29 @@ static FileObject find(URL url) {
         protected @Override URLConnection openConnection(URL u) throws IOException {
             return new MemoryConnection(u);
         }
+
+
+        @Override
+        protected int hashCode(URL u) {
+            int h = 0;
+            String host = u.getHost();
+            if (host != null)
+                h += host.toLowerCase().hashCode();
+            // Generate the file part.
+            String file = u.getFile();
+            if (file != null)
+                h += file.hashCode();
+            // Generate the port part.
+            return h;
+        }
+
+        @Override
+        protected boolean equals(URL u1, URL u2) {
+            return
+                    Objects.equals(u1.getHost(), u2.getHost()) &&
+                    Objects.equals(u1.getFile(), u2.getFile());
+        }
+        
         private static class MemoryConnection extends FileURL {
             MemoryConnection(URL u) {
                 super(u);
diff --git a/openide.windows/apichanges.xml b/openide.windows/apichanges.xml
index 8cdb79835..7169ce81f 100644
--- a/openide.windows/apichanges.xml
+++ b/openide.windows/apichanges.xml
@@ -26,6 +26,21 @@
 <apidef name="winsys">Window System API</apidef>
 </apidefs>
 <changes>
+    <change id="ModeSelector">
+        <api name="winsys"/>
+        <summary>Allow to select Mode for opening a TopComponent instance</summary>
+        <version major="6" minor="6.77"/>
+        <date day="2" month="5" year="2017"/>
+        <author login="sdedic"/>
+        <compatibility addition="yes" semantic="compatible"/>
+        <description>
+            <p>
+                Plugin implementors can direct to-be-opened TopComponents to appropriate Modes or
+                prevent them to open in inappropriate Modes.
+            </p>
+        </description>
+        <class package="org.openide.windows" name="ModeSelector"/>
+    </change>
 <change id="COS_afterRedirect">
     <api name="winsys"/>
     <summary>Added method afterRedirect(CloneableOpenSupport) to CloneableOpenSupport</summary>
diff --git a/openide.windows/manifest.mf b/openide.windows/manifest.mf
index 5a9b76c7f..3f5fe0b1e 100644
--- a/openide.windows/manifest.mf
+++ b/openide.windows/manifest.mf
@@ -1,6 +1,6 @@
 Manifest-Version: 1.0
 OpenIDE-Module: org.openide.windows
-OpenIDE-Module-Specification-Version: 6.76
+OpenIDE-Module-Specification-Version: 6.77
 OpenIDE-Module-Localizing-Bundle: org/openide/windows/Bundle.properties
 AutoUpdate-Essential-Module: true
 
diff --git a/openide.windows/src/org/openide/windows/ModeSelector.java b/openide.windows/src/org/openide/windows/ModeSelector.java
new file mode 100644
index 000000000..a7015894e
--- /dev/null
+++ b/openide.windows/src/org/openide/windows/ModeSelector.java
@@ -0,0 +1,49 @@
+/**
+ * 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.openide.windows;
+
+/**
+ * Selects mode which a TopComponent should initially dock into.
+ * If a TopComponent being opened is not docked into any Mode, the system selects 
+ * the last-used editor-kind Mode, or the default editor mode if no editor was used.
+ * Plugin implementors can hint the Window System to use more appropriate
+ * mode than the default to open the TopComppnent. 
+ * <p/>
+ * If none of the registered {@code ModeSelector}s return a valid Mode, the TopComponent
+ * will open in the mode selected by the default algorithm. Implementation of WindowManager 
+ * may ignore the hint, for example if it conflicts with persisted settings or user choices.
+ * <p/>
+ * Implementations of {@code ModeSelector} must be registered in the default Lookup.
+ * @since 6.77
+ */
+public interface ModeSelector {
+    /**
+     * Choose a suitable Mode to open the TopComponent in. The implementation 
+     * should return an existing Mode which the TopComponent will dock into. The
+     * automatically selected Mode will be passed in {@code preselectedMode}.
+     * The implementation can accept the default or ignore the request and return
+     * {@code null}.
+     * 
+     * @param tc the {@link TopComponent} to be opened.
+     * @param preselectedMode the default mode for opening
+     * @return a more suitable Mode, or {@code null} to use the preselected one.
+     */
+    public Mode selectModeForOpen(TopComponent tc, Mode preselectedMode);
+}
diff --git a/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/InlineMethodTransformer.java b/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/InlineMethodTransformer.java
index ac1fe217e..e354408d8 100644
--- a/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/InlineMethodTransformer.java
+++ b/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/InlineMethodTransformer.java
@@ -26,6 +26,8 @@
 import javax.lang.model.element.*;
 import javax.lang.model.type.ArrayType;
 import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
 import org.netbeans.api.java.source.Comment;
 import org.netbeans.api.java.source.ElementUtilities;
 import org.netbeans.api.java.source.GeneratorUtilities;
@@ -193,6 +195,17 @@ public Tree visitMethodInvocation(MethodInvocationTree node, Element methodEleme
 
             boolean inSameClass = bodyEnclosingTypeElement.equals(invocationEnclosingTypeElement);
             boolean inStatic = !methodElement.getModifiers().contains(Modifier.STATIC) && isInStaticContext(methodInvocationPath);
+            boolean invokeOnInstance = false;
+            MethodInvocationTree invTree = (MethodInvocationTree)methodInvocationPath.getLeaf();
+            if (!methodElement.getModifiers().contains(Modifier.STATIC) && invTree.getMethodSelect().getKind() == Tree.Kind.MEMBER_SELECT) {
+                invokeOnInstance = true;
+                MemberSelectTree mst = (MemberSelectTree)invTree.getMethodSelect();
+                if (mst.getExpression().getKind() == Tree.Kind.IDENTIFIER) {
+                    // check for this.method(). super. qualifier should be omitted if and only if the symbols is not shadowed in subclass.
+                    Name n = ((IdentifierTree)mst.getExpression()).getName();
+                    invokeOnInstance = !(n.contentEquals("this")); // NOI18N
+                }
+            }
 
             TreePath statementPath = findCorrespondingStatement(methodInvocationPath);
             StatementTree statementTree = (StatementTree) statementPath.getLeaf();
@@ -250,7 +263,7 @@ public Void visitReturn(ReturnTree node, Void p) {
             // Add statements up to the last statement (return)
             for (int i = 0; i < body.getStatements().size() - 1; i++) {
                 StatementTree statement = body.getStatements().get(i);
-                if (!inSameClass || inStatic) {
+                if ((!inSameClass || invokeOnInstance) || inStatic) {
                     statement = (StatementTree) fixReferences(statement, new TreePath(bodyPath, statement), method, scope, methodSelect);
                     if (!inSameClass) {
                         statement = genUtils.importFQNs(statement);
@@ -286,7 +299,7 @@ public Void visitReturn(ReturnTree node, Void p) {
             } else {
                 lastStatement = null;
             }
-            if (lastStatement != null && (!inSameClass || inStatic)) {
+            if (lastStatement != null && ((!inSameClass || invokeOnInstance) || inStatic)) {
                 lastStatement = fixReferences(lastStatement, new TreePath(bodyPath, lastStatement), method, scope, methodSelect);
                 if (!inSameClass) {
                     lastStatement = genUtils.importFQNs(lastStatement);
@@ -405,11 +418,12 @@ public Void visitIdentifier(IdentifierTree node, ExecutableElement p) {
                 }
                 Element el = trees.getElement(currentPath);
                 if (el != null) {
-                    DeclaredType declaredType = workingCopy.getTypes().getDeclaredType(scope.getEnclosingClass());
-                    if (methodSelect != null
+                    TypeMirror targetType = el.getEnclosingElement().asType();
+                    if (methodSelect != null 
+                            && targetType != null && targetType.getKind() == TypeKind.DECLARED 
                             && el.getEnclosingElement() != method
-                            && !workingCopy.getTrees().isAccessible(scope, el, declaredType)) {
-                        problem = JavaPluginUtils.chainProblems(problem, new Problem(false, WRN_InlineNotAccessible(el, declaredType)));
+                            && !workingCopy.getTrees().isAccessible(scope, el, (DeclaredType)targetType)) {
+                        problem = JavaPluginUtils.chainProblems(problem, new Problem(false, WRN_InlineNotAccessible(el, targetType)));
                     }
                     TypeElement invocationEnclosingTypeElement = elementUtilities.enclosingTypeElement(el);
                     if (el.getKind() != ElementKind.LOCAL_VARIABLE && bodyEnclosingTypeElement.equals(invocationEnclosingTypeElement)) {
diff --git a/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/JavaPluginUtils.java b/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/JavaPluginUtils.java
index 67da60948..5fe5729b7 100644
--- a/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/JavaPluginUtils.java
+++ b/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/JavaPluginUtils.java
@@ -359,7 +359,7 @@ public static boolean isSyntheticPath(CompilationInfo ci, TreePath path) {
         
         return false;
     }
-
+    
     //<editor-fold defaultstate="collapsed" desc="TODO: Copied from java.source.base TreeUtilities">
     static boolean isSynthetic(CompilationInfo info, CompilationUnitTree cut, Tree leaf) throws NullPointerException {
         JCTree tree = (JCTree) leaf;
diff --git a/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/ReplaceConstructorWithBuilderPlugin.java b/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/ReplaceConstructorWithBuilderPlugin.java
index 8f2d887c8..4114b4762 100644
--- a/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/ReplaceConstructorWithBuilderPlugin.java
+++ b/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/ReplaceConstructorWithBuilderPlugin.java
@@ -71,6 +71,7 @@ public ReplaceConstructorWithBuilderPlugin(ReplaceConstructorWithBuilderRefactor
 
     @Override
     protected Problem preCheck(CompilationController javac) throws IOException {
+        javac.toPhase(JavaSource.Phase.RESOLVED);
         Element constr = treePathHandle.resolveElement(javac);
         if(constr == null || constr.getKind() != ElementKind.CONSTRUCTOR) {
             return new Problem(true, ERR_ReplaceWrongType());
diff --git a/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/ReplaceConstructorWithFactoryPlugin.java b/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/ReplaceConstructorWithFactoryPlugin.java
index d1b78de82..e2b1269d4 100644
--- a/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/ReplaceConstructorWithFactoryPlugin.java
+++ b/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/ReplaceConstructorWithFactoryPlugin.java
@@ -63,6 +63,7 @@ public ReplaceConstructorWithFactoryPlugin(ReplaceConstructorWithFactoryRefactor
 
     @Override
     protected Problem preCheck(CompilationController javac) throws IOException {
+        javac.toPhase(JavaSource.Phase.RESOLVED);
         Element constr = treePathHandle.resolveElement(javac);
         if(constr.getKind() != ElementKind.CONSTRUCTOR) {
             return new Problem(true, ERR_ReplaceWrongType());
diff --git a/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/ChangeParametersAction.java b/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/ChangeParametersAction.java
index 20340255c..bb7676e69 100644
--- a/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/ChangeParametersAction.java
+++ b/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/ChangeParametersAction.java
@@ -37,7 +37,7 @@
 @ActionRegistration(displayName = "#LBL_ChangeMethodSignatureAction", lazy = false)
 @ActionReferences({
     @ActionReference(path = "Editors/text/x-java/RefactoringActions", name = "CallHierarchyAction", position = 430),
-    @ActionReference(path = "Shortcuts", name = "OCS-C")
+    @ActionReference(path = "Shortcuts", name = "CS-Y C")
 })
 public class ChangeParametersAction extends JavaRefactoringGlobalAction {
     
diff --git a/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/EncapsulateFieldAction.java b/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/EncapsulateFieldAction.java
index f14887211..0af28da59 100644
--- a/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/EncapsulateFieldAction.java
+++ b/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/EncapsulateFieldAction.java
@@ -30,7 +30,7 @@
 @ActionRegistration(displayName = "#LBL_EncapsulateFieldsAction", lazy = false)
 @ActionReferences({
     @ActionReference(path = "Editors/text/x-java/RefactoringActions", name = "EncapsulateFieldAction", position = 1800),
-    @ActionReference(path = "Shortcuts", name = "OCS-E")
+    @ActionReference(path = "Shortcuts", name = "CS-Y E")
 })
 public final class EncapsulateFieldAction extends JavaRefactoringGlobalAction {
 
diff --git a/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/ExtractInterfaceAction.java b/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/ExtractInterfaceAction.java
index 180eb04d7..2663530f6 100644
--- a/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/ExtractInterfaceAction.java
+++ b/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/ExtractInterfaceAction.java
@@ -33,7 +33,7 @@
 @ActionRegistration(displayName = "#LBL_ExtractInterface_Action", lazy = false)
 @ActionReferences({
     @ActionReference(path = "Editors/text/x-java/RefactoringActions", name = "ExtractInterfaceAction", position = 700),
-    @ActionReference(path = "Shortcuts", name = "OCS-T")
+    @ActionReference(path = "Shortcuts", name = "CS-Y T")
 })
 public final class ExtractInterfaceAction extends JavaRefactoringGlobalAction {
 
diff --git a/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/ExtractSuperclassAction.java b/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/ExtractSuperclassAction.java
index ee80ef859..a55bc1c98 100644
--- a/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/ExtractSuperclassAction.java
+++ b/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/ExtractSuperclassAction.java
@@ -33,7 +33,7 @@
 @ActionRegistration(displayName = "#LBL_ExtractSC_Action", lazy = false)
 @ActionReferences({
     @ActionReference(path = "Editors/text/x-java/RefactoringActions", name = "ExtractSuperclassAction", position = 800),
-    @ActionReference(path = "Shortcuts", name = "OCS-S")
+    @ActionReference(path = "Shortcuts", name = "CS-Y S")
 })
 public final class ExtractSuperclassAction extends JavaRefactoringGlobalAction {
 
diff --git a/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/InnerToOuterAction.java b/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/InnerToOuterAction.java
index 5bbfa1464..e88574e57 100644
--- a/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/InnerToOuterAction.java
+++ b/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/InnerToOuterAction.java
@@ -35,7 +35,7 @@
 @ActionRegistration(displayName = "#LBL_InnerToOuter_Action", lazy = false)
 @ActionReferences({
     @ActionReference(path = "Editors/text/x-java/RefactoringActions" , name = "InnerToOuterAction", position = 1000),
-    @ActionReference(path = "Shortcuts", name = "OCS-L"),
+    @ActionReference(path = "Shortcuts", name = "CS-Y L"),
 })
 public class InnerToOuterAction extends JavaRefactoringGlobalAction {
     
diff --git a/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/InvertBooleanAction.java b/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/InvertBooleanAction.java
index d1ca88a11..9038d959c 100644
--- a/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/InvertBooleanAction.java
+++ b/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/InvertBooleanAction.java
@@ -33,7 +33,7 @@
 @ActionRegistration(displayName = "#LBL_InvertBooleanAction")
 @ActionReferences({
     @ActionReference(path = "Editors/text/x-java/RefactoringActions", name = "InvertBooleanAction", position = 1830),
-    @ActionReference(path = "Shortcuts", name = "OCS-I")
+    @ActionReference(path = "Shortcuts", name = "CS-Y I")
 })
 public final class InvertBooleanAction extends JavaRefactoringGlobalAction {
 
diff --git a/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/PullUpAction.java b/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/PullUpAction.java
index dd5d9191d..7fb9de507 100644
--- a/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/PullUpAction.java
+++ b/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/PullUpAction.java
@@ -34,7 +34,7 @@
 @ActionRegistration(displayName = "#LBL_PullUp_Action", lazy = false)
 @ActionReferences({
     @ActionReference(path = "Editors/text/x-java/RefactoringActions", name = "PullUpAction", position = 500),
-    @ActionReference(path = "Shortcuts", name = "OCS-U")
+    @ActionReference(path = "Shortcuts", name = "CS-Y U")
 })
 public class PullUpAction extends JavaRefactoringGlobalAction {
 
diff --git a/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/PushDownAction.java b/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/PushDownAction.java
index 87cf15d11..fdd2e066f 100644
--- a/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/PushDownAction.java
+++ b/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/PushDownAction.java
@@ -35,7 +35,7 @@
 @ActionRegistration(displayName = "#LBL_PushDown_Action", lazy = false)
 @ActionReferences({
     @ActionReference(path = "Editors/text/x-java/RefactoringActions", name = "PushDownAction", position = 600),
-    @ActionReference(path = "Shortcuts", name = "OCS-D")
+    @ActionReference(path = "Shortcuts", name = "CS-Y D")
 })
 public class PushDownAction extends JavaRefactoringGlobalAction {
     
diff --git a/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/ReplaceConstructorWithBuilderAction.java b/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/ReplaceConstructorWithBuilderAction.java
index d35b2f4e8..ff1344ff0 100644
--- a/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/ReplaceConstructorWithBuilderAction.java
+++ b/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/ReplaceConstructorWithBuilderAction.java
@@ -35,7 +35,7 @@
 @ActionRegistration(displayName = "#LBL_ReplaceConstructorWithBuilderAction")
 @ActionReferences({
     @ActionReference(path = "Editors/text/x-java/RefactoringActions" , name = "ReplaceConstructorWithBuilderAction", position = 1825),
-    @ActionReference(path = "Shortcuts", name = "OCS-B")
+    @ActionReference(path = "Shortcuts", name = "CS-Y B")
 })
 public final class ReplaceConstructorWithBuilderAction extends JavaRefactoringGlobalAction {
 
diff --git a/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/ReplaceConstructorWithFactoryAction.java b/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/ReplaceConstructorWithFactoryAction.java
index 21b153936..dea651b32 100644
--- a/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/ReplaceConstructorWithFactoryAction.java
+++ b/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/ReplaceConstructorWithFactoryAction.java
@@ -32,7 +32,7 @@
 @ActionRegistration(displayName = "#LBL_ReplaceConstructorAction")
 @ActionReferences({
     @ActionReference(path = "Editors/text/x-java/RefactoringActions", name = "ReplaceConstructorWithFactoryAction", position = 1820),
-    @ActionReference(path = "Shortcuts", name = "OCS-F")
+    @ActionReference(path = "Shortcuts", name = "CS-Y F")
 })
 public final class ReplaceConstructorWithFactoryAction extends JavaRefactoringGlobalAction {
 
diff --git a/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/UseSuperTypeAction.java b/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/UseSuperTypeAction.java
index 3a9e1c202..42883a0ec 100644
--- a/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/UseSuperTypeAction.java
+++ b/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/UseSuperTypeAction.java
@@ -41,7 +41,7 @@
 @ActionRegistration(displayName = "#LBL_UseSuperType_Action", lazy = false)
 @ActionReferences({
     @ActionReference(path = "Editors/text/x-java/RefactoringActions", name = "UseSuperTypeAction", position = 900),
-    @ActionReference(path = "Shortcuts", name = "OCS-W")
+    @ActionReference(path = "Shortcuts", name = "CS-Y W")
 })
 public class UseSuperTypeAction extends JavaRefactoringGlobalAction{
     
diff --git a/refactoring.java/test/unit/src/org/netbeans/modules/refactoring/java/test/InlineTest.java b/refactoring.java/test/unit/src/org/netbeans/modules/refactoring/java/test/InlineTest.java
index 70b473316..f007ce0c4 100644
--- a/refactoring.java/test/unit/src/org/netbeans/modules/refactoring/java/test/InlineTest.java
+++ b/refactoring.java/test/unit/src/org/netbeans/modules/refactoring/java/test/InlineTest.java
@@ -47,7 +47,7 @@ public InlineTest(String name) {
     static {
         JavacParser.DISABLE_SOURCE_LEVEL_DOWNGRADE = true;
     }
-    
+
     public void test258579b() throws Exception {
         writeFilesAndWaitForScan(src,
                 new File("t/A.java", "package t;\n"
@@ -769,7 +769,7 @@ public void test208741() throws Exception {
                 + "}"));
         final InlineRefactoring[] r = new InlineRefactoring[1];
         createInlineMethodRefactoring(src.getFileObject("t/A.java"), 3, r);
-        performRefactoring(r, new Problem(false, "WRN_InlineNotAccessible"));
+        performRefactoring(r);
         verifyContent(src,
                 new File("t/A.java", "package t;\n"
                 + "public class A {\n"
@@ -2198,6 +2198,78 @@ public void run(CompilationController parameter) throws Exception {
                 + "    }\n"
                 + "}"));
     }
+    
+    /**
+     * Checks that the instance used to invoke the method will be used in dereferenced instance's members
+     */
+    public void test271065InlineMethod() throws Exception {
+        writeFilesAndWaitForScan(src,
+                new File("t/TestInline.java", "package t;\n"
+                        + "public class TestInline {\n"
+                        + "    protected Object[] entities;\n"
+                        + "\n"
+                        + "    public Object[] getEntities() {\n"
+                        + "        return entities;\n"
+                        + "    }\n"
+                        + "\n"
+                        + "    public void copy(TestInline source)\n"
+                        + "    {\n"
+                        + "        this.entities = source.getEntities();\n"
+                        + "    }\n"
+                        + "}")
+        );
+        final InlineRefactoring[] r = new InlineRefactoring[1];
+        createInlineMethodRefactoring(src.getFileObject("t/TestInline.java"), 2, r);
+        performRefactoring(r);
+        verifyContent(src,
+                new File("t/TestInline.java", "package t;\n"
+                        + "public class TestInline {\n"
+                        + "    protected Object[] entities;\n"
+                        + "\n"
+                        + "    public void copy(TestInline source)\n"
+                        + "    {\n"
+                        + "        this.entities = source.entities;\n"
+                        + "    }\n"
+                        + "}")
+        );
+    }
+    
+    /**
+     * "this" qualifier should be suppressed.
+     */
+    public void test271065InlineMethodReduceThis() throws Exception {
+        writeFilesAndWaitForScan(src,
+                new File("t/TestInline4.java", "package t;\n"
+                        + "public class TestInline4 {\n"
+                        + "    protected Object[] entities;\n"
+                        + "    protected Object[] entities2;\n"
+                        + "    \n"
+                        + "    public Object[] getEntities() {\n"
+                        + "        return entities;\n"
+                        + "    }\n"
+                        + "\n"
+                        + "    public void copy()\n"
+                        + "    {\n"
+                        + "        this.entities2 = this.getEntities();\n"
+                        + "    }\n"
+                        + "}")
+        );
+        final InlineRefactoring[] r = new InlineRefactoring[1];
+        createInlineMethodRefactoring(src.getFileObject("t/TestInline4.java"), 3, r);
+        performRefactoring(r);
+        verifyContent(src,
+                new File("t/TestInline4.java", "package t;\n"
+                        + "public class TestInline4 {\n"
+                        + "    protected Object[] entities;\n"
+                        + "    protected Object[] entities2;\n"
+                        + "    \n"
+                        + "    public void copy()\n"
+                        + "    {\n"
+                        + "        this.entities2 = entities;\n"
+                        + "    }\n"
+                        + "}")
+        );
+    }
 
     private void createInlineConstantRefactoring(FileObject source, final int position, final InlineRefactoring[] r) throws IOException, IllegalArgumentException {
         JavaSource.forFileObject(source).runUserActionTask(new Task<CompilationController>() {
diff --git a/xml.schema.completion/src/org/netbeans/modules/xml/schema/completion/util/CompletionContextImpl.java b/xml.schema.completion/src/org/netbeans/modules/xml/schema/completion/util/CompletionContextImpl.java
index 0ec947018..b1b416ab2 100644
--- a/xml.schema.completion/src/org/netbeans/modules/xml/schema/completion/util/CompletionContextImpl.java
+++ b/xml.schema.completion/src/org/netbeans/modules/xml/schema/completion/util/CompletionContextImpl.java
@@ -397,9 +397,14 @@ private boolean isTagAttributeRequired(TokenSequence tokenSequence) {
             //this may happen when there's a lexical error inside the tag itself,
             //for example in this valid case: <tag att|> or in something errorneous
             //like: <tag att|#$#$#>
+            isJustBeforeTagErrorToken = false;
+        if (tokID.equals(XMLTokenId.ERROR)) {
             isJustBeforeTagErrorToken 
-                                = tokID.equals(XMLTokenId.ERROR) && diff == 0;
-        
+                                = tokID.equals(XMLTokenId.ERROR);
+            String tokenText = tok.text().toString();
+            isJustBeforeTagErrorToken = tokenText.subSequence(0, diff).toString().trim().isEmpty() ||
+                    diff == 0;
+        }
         while (true) {
             if (tokID.equals(XMLTokenId.TAG) || tokID.equals(XMLTokenId.TEXT)) {
                 if (CompletionUtil.isEndTagPrefix(tok)) break;
@@ -451,7 +456,10 @@ private boolean doInitContext() {
                     String str = token.text().toString();
                     int e = str.length();
                     int l = Math.min(completionAtOffset - tokenOffset /* initial quote */, e);
-                    typedChars = str.substring(0, l);
+                    typedChars = str.substring(0, l).trim();
+                    if (typedChars.isEmpty()) {
+                        typedChars = null;
+                    }
                 }
                 createPathFromRoot(element);
                 return true;
@@ -713,8 +721,11 @@ private void createPathFromRoot(SyntaxElement se) {
         if(se == null)
             return;
         Stack<SyntaxElement> stack = new Stack<>();
-        if(support.isEmptyTag(se))
+        boolean insideEmpty = false;
+        if(support.isEmptyTag(se)) {
             stack.push(se);
+            insideEmpty = true;
+        }
         
         while( se != null) {
             if (
@@ -724,9 +735,13 @@ private void createPathFromRoot(SyntaxElement se) {
                 se = se.getPrevious();
                 continue;
             }
-            if (support.isStartTag(se)) {
-                if (support.isEndTag(stack.peek())) {
-                    SyntaxElement end = stack.peek();
+            if (support.isEmptyTag(se)) {
+                if (insideEmpty) {
+                    stack.pop();
+                }
+            } else if (support.isStartTag(se)) {
+                SyntaxElement end = stack.isEmpty() ? null : stack.peek();
+                if (support.isEndTag(end)) {
                     if(end.getNode().getNodeName().equals(se.getNode().getNodeName())) {
                         stack.pop();
                     }
@@ -734,6 +749,7 @@ private void createPathFromRoot(SyntaxElement se) {
                     stack.push(se);
                 }
             }
+            insideEmpty = false;
             se = se.getPrevious();
         }
         
diff --git a/xml.schema.completion/src/org/netbeans/modules/xml/schema/completion/util/CompletionUtil.java b/xml.schema.completion/src/org/netbeans/modules/xml/schema/completion/util/CompletionUtil.java
index 90d301fb5..8f90dbb80 100644
--- a/xml.schema.completion/src/org/netbeans/modules/xml/schema/completion/util/CompletionUtil.java
+++ b/xml.schema.completion/src/org/netbeans/modules/xml/schema/completion/util/CompletionUtil.java
@@ -584,7 +584,7 @@ public static Element findAXIElementAtContext(
         
         AXIComponent child = null;
         for(QName qname : path) {
-            child = findChildElement(parent, qname);
+            child = findChildElement(parent, qname,context);
             parent = child;
         }
         
@@ -595,17 +595,39 @@ public static Element findAXIElementAtContext(
     }
     
     private static AXIComponent findChildElement(AXIComponent parent,
-            QName qname) {
-        if(parent == null)
+            QName qname, CompletionContextImpl context) {
+        if(parent == null) {
             return null;
+        }
         for(AXIComponent element : parent.getChildElements()) {
             if(!(element instanceof Element)) {
                 continue;
             }
             Element e = (Element)element;
-            if(qname.getLocalPart().equals(e.getName()))
+            if(qname.getLocalPart().equals(e.getName())) {
                 return element;
+            }
+             if(e.isReference()){
+                Element ref=e.getReferent();
+                // check substitutions
+                AXIModel model = ref.getModel();
+                String nsUri = ref.getTargetNamespace();
+                String localName = ref.getName();
+                for (CompletionModel completionModel : context.getCompletionModels()) {
+                    SchemaModel schemaModel = completionModel.getSchemaModel();
+                    Set<GlobalElement> substitutions = FindSubstitutions.resolveSubstitutions(schemaModel, nsUri, localName);
+                    for (GlobalElement substitution : substitutions) {
+                        AXIComponent substitutionElement = getAxiComponent(model, substitution);
+                        if(substitutionElement instanceof Element){
+                            if(((Element)substitutionElement).getName().equals(qname.getLocalPart())) {
+                                return substitutionElement;
+                            }
+                        }
+                    }
+                }
+            }
         }
+        
         for (AXIComponent c : parent.getChildren()) {
             if (c instanceof SchemaReference) {
                 SchemaReference ref = (SchemaReference)c;
@@ -614,7 +636,7 @@ private static AXIComponent findChildElement(AXIComponent parent,
                 try {
                     model = in.resolveReferencedModel();
                     AXIModel am = AXIModelFactory.getDefault().getModel(model);
-                    AXIComponent check = findChildElement(am.getRoot(), qname);
+                    AXIComponent check = findChildElement(am.getRoot(), qname, context);
                     if (check != null) {
                         return check;
                     }
diff --git a/xml.text/src/org/netbeans/modules/xml/text/api/dom/XMLSyntaxSupport.java b/xml.text/src/org/netbeans/modules/xml/text/api/dom/XMLSyntaxSupport.java
index 8c2933564..ccd0d4149 100644
--- a/xml.text/src/org/netbeans/modules/xml/text/api/dom/XMLSyntaxSupport.java
+++ b/xml.text/src/org/netbeans/modules/xml/text/api/dom/XMLSyntaxSupport.java
@@ -530,7 +530,9 @@ public SyntaxElement getElementChain(final int offset ) throws BadLocationExcept
                 case PI_TARGET: {
                     Token<XMLTokenId> first = token;
                     while(token.id() != XMLTokenId.PI_START) {
-                        ts.movePrevious();
+                        if (!ts.movePrevious()) {
+                            break;
+                        }
                         token = ts.token();
                     }
                     return createElement(ts, token);
@@ -620,7 +622,9 @@ private SyntaxElement createElement(final TokenSequence ts,
                         target = t.text().toString();
                     if(t.id() == XMLTokenId.PI_CONTENT)
                         content = t.text().toString();
-                    ts.moveNext();
+                    if (!ts.moveNext()) {
+                        break;
+                    }
                     t = ts.token();
                 }
                 end = ts.offset() + t.length();
@@ -673,7 +677,9 @@ private SyntaxElement createElement(final TokenSequence ts,
             case TAG: {
                 Token<XMLTokenId> t = token;
                 do {
-                    ts.moveNext();
+                    if (!ts.moveNext()) {
+                        break;
+                    }
                     t = ts.token();
                 } while(t.id() != XMLTokenId.TAG);
                 end = ts.offset() + t.length();
diff --git a/xml.text/src/org/netbeans/modules/xml/text/completion/XMLCompletionProvider.java b/xml.text/src/org/netbeans/modules/xml/text/completion/XMLCompletionProvider.java
index 343834ad6..87092be90 100644
--- a/xml.text/src/org/netbeans/modules/xml/text/completion/XMLCompletionProvider.java
+++ b/xml.text/src/org/netbeans/modules/xml/text/completion/XMLCompletionProvider.java
@@ -146,7 +146,9 @@ boolean noCompletion(XMLSyntaxSupport support, JTextComponent target) {
             return support.<Boolean>runWithSequence(offset, (TokenSequence ts) -> {
                 Token<XMLTokenId> token = ts.token();
                 if (token == null) {
-                    ts.moveNext();
+                    if (!ts.moveNext()) {
+                        return false;
+                    }
                     token = ts.token();
                     if (token == null) {
                         return false;
diff --git a/xml.text/src/org/netbeans/modules/xml/text/resources/Bundle.properties b/xml.text/src/org/netbeans/modules/xml/text/resources/Bundle.properties
index e75c1346d..eb9824880 100644
--- a/xml.text/src/org/netbeans/modules/xml/text/resources/Bundle.properties
+++ b/xml.text/src/org/netbeans/modules/xml/text/resources/Bundle.properties
@@ -38,8 +38,8 @@ xml-ws=Markup Whitespace
 xml-operator=Operators
 xml-EOL=New Line (deprecated)
 xml-pi-start=PI Start Delimiter
-xml-pi-end=PI End Delimiter
-xml-pi-target=PI Target
+pi-end=PI End Delimiter
+pi-target=PI Target
 xml-pi-content=PI Content
 xml-cdata-section=CDATA Section
 
diff --git a/xml.text/src/org/netbeans/modules/xml/text/resources/XML-fontsColors.xml b/xml.text/src/org/netbeans/modules/xml/text/resources/XML-fontsColors.xml
index 29d9bb860..62dbcab84 100644
--- a/xml.text/src/org/netbeans/modules/xml/text/resources/XML-fontsColors.xml
+++ b/xml.text/src/org/netbeans/modules/xml/text/resources/XML-fontsColors.xml
@@ -31,8 +31,8 @@
     </fontcolor>
     <fontcolor name="xml-error" default="error"/>
     <fontcolor name="xml-operator" default="operator"/>
-    <fontcolor name="xml-pi-content" foreColor="ff00007c" default="default"/>
-    <fontcolor name="xml-pi-end" foreColor="ff00007c" default="default">
+    <fontcolor name="pi-content" foreColor="ff00007c" default="default"/>
+    <fontcolor name="pi-end" foreColor="ff00007c" default="default">
         <font style="bold"/>
     </fontcolor>
     <fontcolor name="xml-pi-start" foreColor="ff00007c" default="default">
diff --git a/xml.text/src/org/netbeans/modules/xml/text/resources/XMLEditor-fontsColors.xml b/xml.text/src/org/netbeans/modules/xml/text/resources/XMLEditor-fontsColors.xml
deleted file mode 100644
index 14728dbcf..000000000
--- a/xml.text/src/org/netbeans/modules/xml/text/resources/XMLEditor-fontsColors.xml
+++ /dev/null
@@ -1,75 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-    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.
-
--->
-
-<!DOCTYPE fontscolors PUBLIC "-//NetBeans//DTD Editor Fonts and Colors settings 1.0//EN"
-                             "http://www.netbeans.org/dtds/EditorFontsColors-1_0.dtd">
-
-<fontscolors>
-    <fontcolor syntaxName="xml-cdata-section" foreColor="#7C6200">
-        <font name="Monospaced" style="plain" />
-    </fontcolor>
-    <fontcolor syntaxName="xml-pi-target" foreColor="#00007C">
-        <font name="Monospaced" style="bold" />
-    </fontcolor>
-    <fontcolor syntaxName="xml-ref" foreColor="#B20000">
-        <font name="Monospaced" style="plain" />
-    </fontcolor>
-    <fontcolor syntaxName="xml-pi-end" foreColor="#00007C">
-        <font name="Monospaced" style="bold" />
-    </fontcolor>
-    <fontcolor syntaxName="xml-doctype" foreColor="#00007C">
-        <font name="Monospaced" style="bold" />
-    </fontcolor>
-    <fontcolor syntaxName="xml-pi-content" foreColor="#00007C">
-        <font name="Monospaced" style="plain" />
-    </fontcolor>
-    <fontcolor syntaxName="xml-value" foreColor="#99006B">
-        <font name="Monospaced" style="plain" />
-    </fontcolor>
-    <fontcolor syntaxName="xml-operator" foreColor="#007C00">
-        <font name="Monospaced" style="plain" />
-    </fontcolor>
-    <fontcolor syntaxName="xml-comment" foreColor="#808080">
-        <font name="Monospaced" style="italic" />
-    </fontcolor>
-    <fontcolor syntaxName="xml-attribute" foreColor="#007C00">
-        <font name="Monospaced" style="plain" />
-    </fontcolor>
-    <fontcolor syntaxName="xml-tag" foreColor="#0000FF">
-        <font name="Monospaced" style="plain" />
-    </fontcolor>
-    <fontcolor syntaxName="xml-pi-start" foreColor="#00007C">
-        <font name="Monospaced" style="bold" />
-    </fontcolor>
-    <fontcolor syntaxName="xml-text">
-        <font name="Monospaced" style="plain" />
-    </fontcolor>
-    <fontcolor syntaxName="xml-error" foreColor="#FFFFFF" bgColor="#FF0000">
-        <font name="Monospaced" style="plain" />
-    </fontcolor>
-    <fontcolor syntaxName="xml-ws">
-        <font name="Monospaced" style="plain" />
-    </fontcolor>
-    <fontcolor syntaxName="default" foreColor="#000000" bgColor="#FFFFFF">
-        <font name="Monospaced" size="15" style="plain" />
-    </fontcolor>
-</fontscolors>


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services