Merge pull request #2118 from hectorespert/tests_xml_schema_completion

[TRAVIS] Run xml.schema.completion tests
diff --git a/ergonomics/ide.ergonomics/nbproject/project.properties b/ergonomics/ide.ergonomics/nbproject/project.properties
index b11a5b9..cf4591f 100644
--- a/ergonomics/ide.ergonomics/nbproject/project.properties
+++ b/ergonomics/ide.ergonomics/nbproject/project.properties
@@ -28,7 +28,8 @@
 
 test.config.commit.includes=\
     org/netbeans/modules/ide/ergonomics/DynamicVerifyTest.class,\
-    org/netbeans/modules/ide/ergonomics/CachingPreventsLoadingOfModuleManifestsTest.class
+    org/netbeans/modules/ide/ergonomics/CachingPreventsLoadingOfModuleManifestsTest.class,\
+    **/ConfigurationPanelTest.class
 
 test.config.stableBTD.includes=**/*Test.class
 test.config.stableBTD.excludes=\
diff --git a/ergonomics/ide.ergonomics/src/org/netbeans/modules/ide/ergonomics/fod/ConfigurationPanel.java b/ergonomics/ide.ergonomics/src/org/netbeans/modules/ide/ergonomics/fod/ConfigurationPanel.java
index 6d27312..da9b7ce 100644
--- a/ergonomics/ide.ergonomics/src/org/netbeans/modules/ide/ergonomics/fod/ConfigurationPanel.java
+++ b/ergonomics/ide.ergonomics/src/org/netbeans/modules/ide/ergonomics/fod/ConfigurationPanel.java
@@ -24,10 +24,13 @@
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
+import static java.util.Objects.nonNull;
 import java.util.Set;
 import java.util.concurrent.Callable;
 import javax.swing.Box;
@@ -138,29 +141,17 @@
             downloadLabel.setVisible(true);
             activateButton.setVisible(true);
             downloadButton.setVisible(true);
-            StringBuilder sbDownload = new StringBuilder();
-
+            
             // collect descriptions from features contributing installed extras
-            for (FeatureInfo fi : extrasMap.values()) {
-                String s = required
-                        ? fi.getExtraModulesRequiredText()
-                        : fi.getExtraModulesRecommendedText();
-                if (s != null) {
-                    if (sbDownload.length() > 0) {
-                        sbDownload.append("\n");
-                    }
-                    sbDownload.append(s);
-                }
-            }
+            List<String> downloadStringList = collectExtraModulesTextsFromFeatures(extrasMap.values(), required);
+            String lblDownloadMsg = generateDownloadMessageFromExtraModulesTexts(downloadStringList);
+            
             if (required) {
                 activateButton.setEnabled(false);
             } else {
                 activateButton.setEnabled(true);
             }
 
-            String lblDownloadMsg = sbDownload.toString();
-
-            String list = "";
             if (!missingModules.isEmpty()) {
                 StringBuilder sb = new StringBuilder();
                 for (FeatureInfo.ExtraModuleInfo s : missingModules) {
@@ -169,7 +160,7 @@
                     }
                     sb.append(s.displayName());
                 }
-                list = sb.toString();
+                String list = sb.toString();
                 if (required) {
                     lblDownloadMsg = NbBundle.getMessage(ConfigurationPanel.class, "MSG_MissingRequiredModules", displayName, list);
                     activateButton.setEnabled(false);
@@ -190,6 +181,40 @@
             org.openide.awt.Mnemonics.setLocalizedText(downloadButton, btnDownloadMsg);
         }
     }
+    
+    /**
+     * Collect extra modules texts
+     */
+    protected List<String> collectExtraModulesTextsFromFeatures(Collection<FeatureInfo> features, boolean required) {
+        List<String> descriptionsList = new ArrayList<>();
+        for (FeatureInfo fi : features) {
+            String s = required ? fi.getExtraModulesRequiredText(): fi.getExtraModulesRecommendedText();
+            if (nonNull(s) && !descriptionsList.contains(s)) {
+                descriptionsList.add(s);
+            }
+        }
+        return descriptionsList;
+    } 
+    
+    /**
+     * Generate download message from extra modules texts
+     * @param extraModulesTexts
+     * @return String Text to set in download label
+     */
+    protected String generateDownloadMessageFromExtraModulesTexts(List<String> extraModulesTexts) {
+        StringBuilder sbDownload = new StringBuilder();
+        if (!extraModulesTexts.isEmpty()) {
+            sbDownload.append("<html><body>");
+            for (int i = 0; i < extraModulesTexts.size(); i++) {
+                sbDownload.append(extraModulesTexts.get(i));
+                if (extraModulesTexts.size() > 1 && i < extraModulesTexts.size() - 1) {
+                    sbDownload.append("<br>");
+                }
+            }
+            sbDownload.append("</body></html>");
+        }
+        return sbDownload.toString();
+    }
 
     @Override
     public void removeNotify() {
diff --git a/ergonomics/ide.ergonomics/test/unit/src/org/netbeans/modules/ide/ergonomics/fod/ConfigurationPanelTest.java b/ergonomics/ide.ergonomics/test/unit/src/org/netbeans/modules/ide/ergonomics/fod/ConfigurationPanelTest.java
new file mode 100644
index 0000000..7972c94
--- /dev/null
+++ b/ergonomics/ide.ergonomics/test/unit/src/org/netbeans/modules/ide/ergonomics/fod/ConfigurationPanelTest.java
@@ -0,0 +1,150 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.ide.ergonomics.fod;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.swing.JPanel;
+import org.netbeans.api.autoupdate.UpdateElement;
+import org.netbeans.junit.NbTestCase;
+
+/**
+ *
+ * @author Hector Espert
+ */
+public class ConfigurationPanelTest extends NbTestCase {
+    
+    private ConfigurationPanel configurationPanel;
+
+    public ConfigurationPanelTest(String name) {
+        super(name);
+    }
+
+    @Override
+    protected boolean runInEQ() {
+        return true;
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        configurationPanel = new ConfigurationPanel(JPanel::new); 
+    }
+    
+    
+    public void testSetInfo() throws Exception {
+        FeatureInfo featureInfo = FeatureInfo.create("TestFactory", 
+                this.getClass().getResource("FeatureInfo.xml"), 
+                this.getClass().getResource("TestBundle.properties"));
+                
+        Collection<UpdateElement> toInstall = new ArrayList<>();
+        
+        Collection<FeatureInfo.ExtraModuleInfo> missingModules = new ArrayList<>();
+        
+        Map<FeatureInfo.ExtraModuleInfo, FeatureInfo> extrasMap = new HashMap<>();
+        
+        FeatureInfo.ExtraModuleInfo extraModuleInfo = new FeatureInfo.ExtraModuleInfo("Feature", null, null);
+        extrasMap.put(extraModuleInfo, featureInfo);
+        
+        configurationPanel.setInfo(featureInfo, null, toInstall, missingModules, extrasMap, true);
+    }
+    
+    
+    public void testCollectExtraModulesTextsFromFeatures() throws IOException {
+        Collection<FeatureInfo> features = new ArrayList<>();
+        
+        List<String> texts = configurationPanel.collectExtraModulesTextsFromFeatures(features, true);
+        assertNotNull(texts);
+        assertTrue(texts.isEmpty());
+        
+        FeatureInfo featureInfo = FeatureInfo.create("TestFactory", 
+                this.getClass().getResource("FeatureInfo.xml"), 
+                this.getClass().getResource("TestBundle.properties"));
+        
+        features.add(featureInfo);
+        
+        texts = configurationPanel.collectExtraModulesTextsFromFeatures(features, true);
+        assertNotNull(texts);
+        assertFalse(texts.isEmpty());
+        
+        List<String> expected = new ArrayList();
+        expected.add("Required");
+        assertEquals(expected, texts);
+        
+        texts = configurationPanel.collectExtraModulesTextsFromFeatures(features, false);
+        assertNotNull(texts);
+        assertFalse(texts.isEmpty());
+        
+        expected = new ArrayList();
+        expected.add("Recommended");
+        assertEquals(expected, texts);
+        
+        FeatureInfo otherFeatureInfo = FeatureInfo.create("TestFactory", 
+                this.getClass().getResource("FeatureInfo.xml"), 
+                this.getClass().getResource("TestBundle.properties"));
+        
+        features.add(otherFeatureInfo);
+        
+        texts = configurationPanel.collectExtraModulesTextsFromFeatures(features, true);
+        assertNotNull(texts);
+        assertFalse(texts.isEmpty());
+        
+        expected = new ArrayList();
+        expected.add("Required");
+        assertEquals(expected, texts);
+        
+        otherFeatureInfo = FeatureInfo.create("TestFactory", 
+                this.getClass().getResource("FeatureInfo.xml"), 
+                this.getClass().getResource("TestBundle2.properties"));
+        
+        features.add(otherFeatureInfo);
+        
+        texts = configurationPanel.collectExtraModulesTextsFromFeatures(features, true);
+        assertNotNull(texts);
+        assertFalse(texts.isEmpty());
+        
+        expected = new ArrayList();
+        expected.add("Required");
+        expected.add("Required2");
+        assertEquals(expected, texts);
+    }
+    
+    public void testGenerateDownloadMessageFromExtraModulesTexts() {
+        List<String> extraModulesTexts = new ArrayList<>();
+        
+        String downloadText = configurationPanel.generateDownloadMessageFromExtraModulesTexts(extraModulesTexts);
+        assertEquals("", downloadText);
+        
+        extraModulesTexts.add("JDK8");
+        downloadText = configurationPanel.generateDownloadMessageFromExtraModulesTexts(extraModulesTexts);
+        assertEquals("<html><body>JDK8</body></html>", downloadText);
+        
+        extraModulesTexts.add("JDK10.5");
+        downloadText = configurationPanel.generateDownloadMessageFromExtraModulesTexts(extraModulesTexts);
+        assertEquals("<html><body>JDK8<br>JDK10.5</body></html>", downloadText);
+        
+        extraModulesTexts.add("JDK14");
+        downloadText = configurationPanel.generateDownloadMessageFromExtraModulesTexts(extraModulesTexts);
+        assertEquals("<html><body>JDK8<br>JDK10.5<br>JDK14</body></html>", downloadText);
+    }
+
+}
diff --git a/ergonomics/ide.ergonomics/test/unit/src/org/netbeans/modules/ide/ergonomics/fod/TestBundle.properties b/ergonomics/ide.ergonomics/test/unit/src/org/netbeans/modules/ide/ergonomics/fod/TestBundle.properties
index 06fe772..f7bea6c 100644
--- a/ergonomics/ide.ergonomics/test/unit/src/org/netbeans/modules/ide/ergonomics/fod/TestBundle.properties
+++ b/ergonomics/ide.ergonomics/test/unit/src/org/netbeans/modules/ide/ergonomics/fod/TestBundle.properties
@@ -20,3 +20,5 @@
 cnbs=org.netbeans.modules.subversion
 project.file.dbproject/project.properties=SomeClass
 
+LBL_Ergonomics_Extra_Required=Required
+LBL_Ergonomics_Extra_Recommended=Recommended
diff --git a/ergonomics/ide.ergonomics/test/unit/src/org/netbeans/modules/ide/ergonomics/fod/TestBundle2.properties b/ergonomics/ide.ergonomics/test/unit/src/org/netbeans/modules/ide/ergonomics/fod/TestBundle2.properties
index 80a685a..b80558b 100644
--- a/ergonomics/ide.ergonomics/test/unit/src/org/netbeans/modules/ide/ergonomics/fod/TestBundle2.properties
+++ b/ergonomics/ide.ergonomics/test/unit/src/org/netbeans/modules/ide/ergonomics/fod/TestBundle2.properties
@@ -18,3 +18,6 @@
 cnbs=org.netbeans.modules.favorites
 project.file.umlproject/project.properties=SomeClass
 
+LBL_Ergonomics_Extra_Required=Required2
+LBL_Ergonomics_Extra_Recommended=Recommended2
+
diff --git a/java/java.hints/src/org/netbeans/modules/java/hints/errors/DifferentCaseKindsFix.java b/java/java.hints/src/org/netbeans/modules/java/hints/errors/DifferentCaseKindsFix.java
index ec75b07..5572337 100644
--- a/java/java.hints/src/org/netbeans/modules/java/hints/errors/DifferentCaseKindsFix.java
+++ b/java/java.hints/src/org/netbeans/modules/java/hints/errors/DifferentCaseKindsFix.java
@@ -44,6 +44,8 @@
  */
 public class DifferentCaseKindsFix implements ErrorRule<Void> {
 
+    private static final int SWITCH_RULE_PREVIEW_JDK_VERSION = 13;
+
     private static final Set<String> ERROR_CODES = new HashSet<String>(Arrays.asList(
             "compiler.err.switch.mixing.case.types")); // NOI18N
     
@@ -54,7 +56,7 @@
 
     @Override
     public List<Fix> run(CompilationInfo info, String diagnosticKey, int offset, TreePath treePath, Data<Void> data) {
-        if (!CompilerOptionsQuery.getOptions(info.getFileObject()).getArguments().contains("--enable-preview")) {
+        if (Utilities.isJDKVersionLower(SWITCH_RULE_PREVIEW_JDK_VERSION) && !CompilerOptionsQuery.getOptions(info.getFileObject()).getArguments().contains("--enable-preview")) {
             return null;
         }
         TreePath parentPath = treePath.getParentPath();
diff --git a/java/java.hints/src/org/netbeans/modules/java/hints/errors/Utilities.java b/java/java.hints/src/org/netbeans/modules/java/hints/errors/Utilities.java
index 9b8f8f9..3f70b14 100644
--- a/java/java.hints/src/org/netbeans/modules/java/hints/errors/Utilities.java
+++ b/java/java.hints/src/org/netbeans/modules/java/hints/errors/Utilities.java
@@ -159,6 +159,7 @@
 public class Utilities {
     public  static final String JAVA_MIME_TYPE = "text/x-java";
     private static final String DEFAULT_NAME = "name";
+    private static final String UNDERSCORE = "_";
     enum SWITCH_TYPE { TRADITIONAL_SWITCH, RULE_SWITCH, SWITCH_EXPRESSION }
 
     public Utilities() {
@@ -3331,4 +3332,11 @@
         JCTree.JCAssign assignTree = (JCTree.JCAssign) jceTree.expr;
         return ((JCTree.JCIdent) assignTree.lhs).name;
     }
+
+    public static boolean isJDKVersionLower(int previewUntilJDK){
+        if(Integer.valueOf(SourceVersion.latest().name().split(UNDERSCORE)[1]).compareTo(previewUntilJDK)<=0)
+            return true;
+
+        return false;
+    }
 }
diff --git a/java/java.hints/src/org/netbeans/modules/java/hints/jdk/ConvertSwitchToRuleSwitch.java b/java/java.hints/src/org/netbeans/modules/java/hints/jdk/ConvertSwitchToRuleSwitch.java
index aa681f6..751f4b2 100644
--- a/java/java.hints/src/org/netbeans/modules/java/hints/jdk/ConvertSwitchToRuleSwitch.java
+++ b/java/java.hints/src/org/netbeans/modules/java/hints/jdk/ConvertSwitchToRuleSwitch.java
@@ -22,6 +22,7 @@
 import com.sun.source.tree.SwitchTree;
 import com.sun.source.tree.Tree;
 import com.sun.source.util.TreePath;
+import javax.lang.model.SourceVersion;
 import org.netbeans.api.java.queries.CompilerOptionsQuery;
 import org.netbeans.api.java.source.CompilationInfo;
 import org.netbeans.modules.java.hints.errors.Utilities;
@@ -43,11 +44,13 @@
     "DESC_org.netbeans.modules.java.hints.jdk.ConvertSwitchStatementToSwitchExpression=Converts to switch expression",
 })
 public class ConvertSwitchToRuleSwitch {
-    
+
+    private static final int SWITCH_RULE_PREVIEW_JDK_VERSION = 13;
+
     @TriggerTreeKind(Tree.Kind.SWITCH)
     @Messages({"ERR_ConvertSwitchToRuleSwitch=Convert switch to rule switch", "ERR_ConvertSwitchToSwitchExpression=Convert to switch expression"})
     public static ErrorDescription switch2RuleSwitch(HintContext ctx) {
-        if (!CompilerOptionsQuery.getOptions(ctx.getInfo().getFileObject()).getArguments().contains("--enable-preview"))
+        if (Utilities.isJDKVersionLower(SWITCH_RULE_PREVIEW_JDK_VERSION) && !CompilerOptionsQuery.getOptions(ctx.getInfo().getFileObject()).getArguments().contains("--enable-preview"))
             return null;
         SwitchTree st = (SwitchTree) ctx.getPath().getLeaf();
         boolean completesNormally = false;
diff --git a/java/java.hints/src/org/netbeans/modules/java/hints/jdk/ConvertToPatternInstanceOf.java b/java/java.hints/src/org/netbeans/modules/java/hints/jdk/ConvertToPatternInstanceOf.java
index 90699b4..e397ed8 100644
--- a/java/java.hints/src/org/netbeans/modules/java/hints/jdk/ConvertToPatternInstanceOf.java
+++ b/java/java.hints/src/org/netbeans/modules/java/hints/jdk/ConvertToPatternInstanceOf.java
@@ -64,7 +64,8 @@
     "ERR_ConvertToPatternInstanceOf=instanceof <pattern> can be used here",
     "FIX_ConvertToPatternInstanceOf=Use instanceof <pattern>"
 })
-@Hint(displayName="#DN_ConvertToPatternInstanceOf", description="#DESC_ConvertToPatternInstanceOf", category="rules15")
+@Hint(displayName="#DN_ConvertToPatternInstanceOf", description="#DESC_ConvertToPatternInstanceOf", category="rules15",
+        minSourceVersion = "14")
 public class ConvertToPatternInstanceOf {
     
     @TriggerPatterns({
diff --git a/java/java.hints/test/unit/src/org/netbeans/modules/java/hints/errors/DifferentCaseKindsFixTest.java b/java/java.hints/test/unit/src/org/netbeans/modules/java/hints/errors/DifferentCaseKindsFixTest.java
index b9cacff..936f8ae 100644
--- a/java/java.hints/test/unit/src/org/netbeans/modules/java/hints/errors/DifferentCaseKindsFixTest.java
+++ b/java/java.hints/test/unit/src/org/netbeans/modules/java/hints/errors/DifferentCaseKindsFixTest.java
@@ -22,6 +22,7 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
+import javax.lang.model.SourceVersion;
 import javax.swing.event.ChangeListener;
 import org.netbeans.api.java.source.CompilationInfo;
 import org.netbeans.modules.java.hints.infrastructure.ErrorHintsTestBase;
@@ -47,9 +48,16 @@
     @Override
     protected void setUp() throws Exception {
         super.setUp();
-        sourceLevel = "13";
         JavacParser.DISABLE_SOURCE_LEVEL_DOWNGRADE = true;
-        EXTRA_OPTIONS.add("--enable-preview");
+        try {
+            SourceVersion.valueOf("RELEASE_14"); //NOI18N
+        } catch (IllegalArgumentException ex) {
+            //OK, no RELEASE_14, skip test
+            sourceLevel = "13";
+            EXTRA_OPTIONS.add("--enable-preview");
+            return;
+        }
+        sourceLevel = "14";
     }
 
     @ServiceProvider(service = CompilerOptionsQueryImplementation.class, position = 100)
diff --git a/java/java.hints/test/unit/src/org/netbeans/modules/java/hints/jdk/ConvertSwitchToRuleSwitchTest.java b/java/java.hints/test/unit/src/org/netbeans/modules/java/hints/jdk/ConvertSwitchToRuleSwitchTest.java
index 08e171d..13e3563 100644
--- a/java/java.hints/test/unit/src/org/netbeans/modules/java/hints/jdk/ConvertSwitchToRuleSwitchTest.java
+++ b/java/java.hints/test/unit/src/org/netbeans/modules/java/hints/jdk/ConvertSwitchToRuleSwitchTest.java
@@ -35,7 +35,19 @@
         super(name);
     }
     
+    public static boolean isJDK14(){
+        try {
+            SourceVersion.valueOf("RELEASE_14"); //NOI18N
+        } catch (IllegalArgumentException ex) {
+            //OK, no RELEASE_14, skip test
+            return false;
+        }
+        return true;
+    }
+
     public void testSwitch2RuleSwitch() throws Exception {
+        if(!ConvertSwitchToRuleSwitchTest.isJDK14())
+            return;
         HintTest.create()
                 .input("package test;" +
                        "public class Test {\n" +
@@ -49,7 +61,6 @@
                        "     }\n" +
                        "}\n")
                 .sourceLevel(SourceVersion.latest().name())
-                .options("--enable-preview")
                 .run(ConvertSwitchToRuleSwitch.class)
                 .findWarning("3:9-3:15:verifier:" + Bundle.ERR_ConvertSwitchToRuleSwitch())
                 .applyFix()
@@ -68,6 +79,8 @@
     }
     
     public void testLastNotBreak() throws Exception {
+        if(!ConvertSwitchToRuleSwitchTest.isJDK14())
+            return;
         HintTest.create()
                 .input("package test;" +
                        "public class Test {\n" +
@@ -79,7 +92,6 @@
                        "     }\n" +
                        "}\n")
                 .sourceLevel(SourceVersion.latest().name())
-                .options("--enable-preview")
                 .run(ConvertSwitchToRuleSwitch.class)
                 .findWarning("3:9-3:15:verifier:" + Bundle.ERR_ConvertSwitchToRuleSwitch())
                 .applyFix()
@@ -96,6 +108,8 @@
     }
     
     public void testMultipleCases() throws Exception {
+        if(!ConvertSwitchToRuleSwitchTest.isJDK14())
+            return;
         HintTest.create()
                 .input("package test;" +
                        "public class Test {\n" +
@@ -109,7 +123,6 @@
                        "     }\n" +
                        "}\n")
                 .sourceLevel(SourceVersion.latest().name())
-                .options("--enable-preview")
                 .run(ConvertSwitchToRuleSwitch.class)
                 .findWarning("3:9-3:15:verifier:" + Bundle.ERR_ConvertSwitchToRuleSwitch())
                 .applyFix()
@@ -127,6 +140,8 @@
     }
     
     public void testFallThrough() throws Exception {
+        if(!ConvertSwitchToRuleSwitchTest.isJDK14())
+            return;
         HintTest.create()
                 .input("package test;" +
                        "public class Test {\n" +
@@ -139,12 +154,13 @@
                        "     }\n" +
                        "}\n")
                 .sourceLevel(SourceVersion.latest().name())
-                .options("--enable-preview")
                 .run(ConvertSwitchToRuleSwitch.class)
                 .assertWarnings();
     }
     
     public void testMissingLastBreak() throws Exception {
+        if(!ConvertSwitchToRuleSwitchTest.isJDK14())
+            return;
         HintTest.create()
                 .input("package test;" +
                        "public class Test {\n" +
@@ -158,7 +174,6 @@
                        "     }\n" +
                        "}\n")
                 .sourceLevel(SourceVersion.latest().name())
-                .options("--enable-preview")
                 .run(ConvertSwitchToRuleSwitch.class)
                 .findWarning("3:9-3:15:verifier:" + Bundle.ERR_ConvertSwitchToRuleSwitch())
                 .applyFix()
@@ -176,6 +191,8 @@
     }
 
     public void testDefault() throws Exception {
+        if(!ConvertSwitchToRuleSwitchTest.isJDK14())
+            return;
         HintTest.create()
                 .input("package test;" +
                        "public class Test {\n" +
@@ -188,7 +205,6 @@
                        "     }\n" +
                        "}\n")
                 .sourceLevel(SourceVersion.latest().name())
-                .options("--enable-preview")
                 .run(ConvertSwitchToRuleSwitch.class)
                 .findWarning("3:9-3:15:verifier:" + Bundle.ERR_ConvertSwitchToRuleSwitch())
                 .applyFix()
@@ -208,6 +224,8 @@
     }
 
     public void testVariables1() throws Exception {
+        if(!ConvertSwitchToRuleSwitchTest.isJDK14())
+            return;
         HintTest.create()
                 .input("package test;" +
                        "public class Test {\n" +
@@ -227,7 +245,6 @@
                        "     }\n" +
                        "}\n")
                 .sourceLevel(SourceVersion.latest().name())
-                .options("--enable-preview")
                 .run(ConvertSwitchToRuleSwitch.class)
                 .findWarning("3:9-3:15:verifier:" + Bundle.ERR_ConvertSwitchToRuleSwitch())
                 .applyFix()
@@ -253,6 +270,8 @@
     }
 
     public void testFallThroughDefault1() throws Exception {
+        if(!ConvertSwitchToRuleSwitchTest.isJDK14())
+            return;
         HintTest.create()
                 .input("package test;" +
                        "public class Test {\n" +
@@ -266,12 +285,13 @@
                        "     }\n" +
                        "}\n")
                 .sourceLevel(SourceVersion.latest().name())
-                .options("--enable-preview")
                 .run(ConvertSwitchToRuleSwitch.class)
                 .assertWarnings();
     }
 
     public void testFallThroughDefault2() throws Exception {
+        if(!ConvertSwitchToRuleSwitchTest.isJDK14())
+            return;
         HintTest.create()
                 .input("package test;" +
                        "public class Test {\n" +
@@ -285,12 +305,13 @@
                        "     }\n" +
                        "}\n")
                 .sourceLevel(SourceVersion.latest().name())
-                .options("--enable-preview")
                 .run(ConvertSwitchToRuleSwitch.class)
                 .assertWarnings();
     }
 
     public void testTrailingEmptyCase() throws Exception {
+        if(!ConvertSwitchToRuleSwitchTest.isJDK14())
+            return;
         HintTest.create()
                 .input("package test;" +
                        "public class Test {\n" +
@@ -306,7 +327,6 @@
                        "     }\n" +
                        "}\n")
                 .sourceLevel(SourceVersion.latest().name())
-                .options("--enable-preview")
                 .run(ConvertSwitchToRuleSwitch.class)
                 .findWarning("3:9-3:15:verifier:" + Bundle.ERR_ConvertSwitchToRuleSwitch())
                 .applyFix()
@@ -327,6 +347,8 @@
     }
 
     public void testNeedsPreview() throws Exception {
+        if(ConvertSwitchToRuleSwitchTest.isJDK14())
+            return;
         HintTest.create()
                 .input("package test;" +
                        "public class Test {\n" +
@@ -346,6 +368,8 @@
     }
 
     public void testBreakInside1() throws Exception {
+        if(!ConvertSwitchToRuleSwitchTest.isJDK14())
+            return;
         HintTest.create()
                 .input("package test;" +
                        "public class Test {\n" +
@@ -358,12 +382,13 @@
                        "     }\n" +
                        "}\n")
                 .sourceLevel(SourceVersion.latest().name())
-                .options("--enable-preview")
                 .run(ConvertSwitchToRuleSwitch.class)
                 .assertWarnings();
     }
 
     public void testBreakInside2() throws Exception {
+        if(!ConvertSwitchToRuleSwitchTest.isJDK14())
+            return;
         HintTest.create()
                 .input("package test;\n" +
                        "public class Test {\n" +
@@ -378,7 +403,6 @@
                        "     }\n" +
                        "}\n")
                 .sourceLevel(SourceVersion.latest().name())
-                .options("--enable-preview")
                 .run(ConvertSwitchToRuleSwitch.class)
                 .findWarning("4:9-4:15:verifier:Convert switch to rule switch")
                 .applyFix()
@@ -400,6 +424,8 @@
     }
 
     public void testContinueInside1() throws Exception {
+        if(!ConvertSwitchToRuleSwitchTest.isJDK14())
+            return;
         HintTest.create()
                 .input("package test;\n" +
                        "public class Test {\n" +
@@ -412,12 +438,13 @@
                        "     }\n" +
                        "}\n")
                 .sourceLevel(SourceVersion.latest().name())
-                .options("--enable-preview")
                 .run(ConvertSwitchToRuleSwitch.class)
                 .assertWarnings();
     }
 
     public void testContinueInside2() throws Exception {
+        if(!ConvertSwitchToRuleSwitchTest.isJDK14())
+            return;
         HintTest.create()
                 .input("package test;\n" +
                        "public class Test {\n" +
@@ -434,7 +461,6 @@
                        "     }\n" +
                        "}\n")
                 .sourceLevel(SourceVersion.latest().name())
-                .options("--enable-preview")
                 .run(ConvertSwitchToRuleSwitch.class)
                 .findWarning("5:13-5:19:verifier:Convert switch to rule switch")
                 .applyFix()
@@ -460,6 +486,8 @@
     //Test cases for switch expression
 
     public void testSwitch2SwitchExpression() throws Exception {
+        if(!ConvertSwitchToRuleSwitchTest.isJDK14())
+            return;
         HintTest.create()
                 .input("package test;" +
                        "public class Test {\n" +
@@ -474,7 +502,6 @@
                        "     }\n" +
                        "}\n")
                 .sourceLevel(SourceVersion.latest().name())
-                .options("--enable-preview")
                 .run(ConvertSwitchToRuleSwitch.class)
                 .findWarning("3:9-3:15:verifier:" + Bundle.ERR_ConvertSwitchToSwitchExpression())
                 .applyFix()
@@ -494,6 +521,8 @@
     }
 
     public void testSwitch2SwitchExpressionMultiCase() throws Exception {
+        if(!ConvertSwitchToRuleSwitchTest.isJDK14())
+            return;
         HintTest.create()
                 .input("package test;" +
                        "public class Test {\n" +
@@ -508,7 +537,6 @@
                        "    }\n" +
                        "}\n")
                 .sourceLevel(SourceVersion.latest().name())
-                .options("--enable-preview")
                 .run(ConvertSwitchToRuleSwitch.class)
                 .findWarning("3:8-3:14:verifier:" + Bundle.ERR_ConvertSwitchToSwitchExpression())
                 .applyFix()
@@ -527,6 +555,8 @@
     }
 
     public void testSwitch2SwitchExpressionMultiCase2() throws Exception {
+        if(!ConvertSwitchToRuleSwitchTest.isJDK14())
+            return;
         HintTest.create()
                 .input("package test;" +
                        "public class Test {\n" +
@@ -541,7 +571,6 @@
                        "    }\n" +
                        "}\n")
                 .sourceLevel(SourceVersion.latest().name())
-                .options("--enable-preview")
                 .run(ConvertSwitchToRuleSwitch.class)
                 .findWarning("3:8-3:14:verifier:" + Bundle.ERR_ConvertSwitchToSwitchExpression())
                 .applyFix()
@@ -560,6 +589,8 @@
     }
 
     public void testSwitch2SwitchExpressionOnlyDefault() throws Exception {
+        if(!ConvertSwitchToRuleSwitchTest.isJDK14())
+            return;
         HintTest.create()
                 .input("package test;" +
                        "public class Test {\n" +
@@ -571,7 +602,6 @@
                        "    }\n" +
                        "}\n")
                 .sourceLevel(SourceVersion.latest().name())
-                .options("--enable-preview")
                 .run(ConvertSwitchToRuleSwitch.class)
                 .findWarning("3:8-3:14:verifier:" + Bundle.ERR_ConvertSwitchToSwitchExpression())
                 .applyFix()
@@ -588,6 +618,8 @@
     }
 
     public void testSwitch2SwitchExpressionNestedInnerSwitchExpression() throws Exception {
+        if(!ConvertSwitchToRuleSwitchTest.isJDK14())
+            return;
         HintTest.create()
                 .input("package test;" +
                        "public class Test {\n" +
@@ -605,7 +637,6 @@
                        "     }\n" +
                        "}\n")
                 .sourceLevel(SourceVersion.latest().name())
-                .options("--enable-preview")
                 .run(ConvertSwitchToRuleSwitch.class)
                 .findWarning("4:9-4:15:verifier:" + Bundle.ERR_ConvertSwitchToSwitchExpression())
                 .applyFix()
@@ -628,6 +659,8 @@
     }
 
     public void testSwitch2SwitchExpressionReturnValue() throws Exception {
+        if(!ConvertSwitchToRuleSwitchTest.isJDK14())
+            return;
         HintTest.create()
                 .input("package test;" +
                        "public class Test {\n" +
@@ -639,7 +672,6 @@
                        "     }\n" +
                        "}\n")
                 .sourceLevel(SourceVersion.latest().name())
-                .options("--enable-preview")
                 .run(ConvertSwitchToRuleSwitch.class)
                 .findWarning("2:9-2:15:verifier:" + Bundle.ERR_ConvertSwitchToSwitchExpression())
                 .applyFix()
@@ -656,6 +688,8 @@
     }
 
     public void testSwitch2SwitchExpressionTypeCast() throws Exception {
+        if(!ConvertSwitchToRuleSwitchTest.isJDK14())
+            return;
         HintTest.create()
                 .input("package test;" +
                        "public class Test {\n" +
@@ -668,7 +702,6 @@
                        "     }\n" +
                        "}\n")
                 .sourceLevel(SourceVersion.latest().name())
-                .options("--enable-preview")
                 .run(ConvertSwitchToRuleSwitch.class)
                 .findWarning("3:9-3:15:verifier:" + Bundle.ERR_ConvertSwitchToSwitchExpression())
                 .applyFix()
@@ -686,6 +719,8 @@
     }
 
     public void testSwitch2SwitchExpressionTypeCastReturn() throws Exception {
+        if(!ConvertSwitchToRuleSwitchTest.isJDK14())
+            return;
         HintTest.create()
                 .input("package test;" +
                        "public class Test {\n" +
@@ -697,7 +732,6 @@
                        "     }\n" +
                        "}\n")
                 .sourceLevel(SourceVersion.latest().name())
-                .options("--enable-preview")
                 .run(ConvertSwitchToRuleSwitch.class)
                 .findWarning("2:9-2:15:verifier:" + Bundle.ERR_ConvertSwitchToSwitchExpression())
                 .applyFix()
@@ -714,6 +748,8 @@
     }
 
     public void testSwitch2SwitchExpressionNestedSwitchExpression() throws Exception {
+        if(!ConvertSwitchToRuleSwitchTest.isJDK14())
+            return;
         HintTest.create()
                 .input("package test;" +
                        "public class Test {\n" +
@@ -729,7 +765,6 @@
                        "     }\n" +
                        "}\n")
                 .sourceLevel(SourceVersion.latest().name())
-                .options("--enable-preview")
                 .run(ConvertSwitchToRuleSwitch.class)
                 .findWarning("3:9-3:15:verifier:" + Bundle.ERR_ConvertSwitchToSwitchExpression())
                 .applyFix()
@@ -750,6 +785,8 @@
     }
 
     public void testSwitch2SwitchExpressionNestedOuterSwitchStatement() throws Exception {
+        if(!ConvertSwitchToRuleSwitchTest.isJDK14())
+            return;
         HintTest.create()
                 .input("package test;" +
                        "public class Test {\n" +
@@ -770,7 +807,6 @@
                        "     }\n" +
                        "}\n")
                 .sourceLevel(SourceVersion.latest().name())
-                .options("--enable-preview")
                 .run(ConvertSwitchToRuleSwitch.class)
                 .findWarning("4:9-4:15:verifier:" + Bundle.ERR_ConvertSwitchToRuleSwitch())
                 .applyFix()
@@ -794,6 +830,8 @@
     }
 
     public void testSwitch2SwitchExpressionNestedInnerSwitchStatement() throws Exception {
+        if(!ConvertSwitchToRuleSwitchTest.isJDK14())
+            return;
         HintTest.create()
                 .input("package test;" +
                        "public class Test {\n" +
@@ -814,7 +852,6 @@
                        "     }\n" +
                        "}\n")
                 .sourceLevel(SourceVersion.latest().name())
-                .options("--enable-preview")
                 .run(ConvertSwitchToRuleSwitch.class)
                 .findWarning("6:16-6:22:verifier:" + Bundle.ERR_ConvertSwitchToSwitchExpression())
                 .applyFix()
diff --git a/java/java.j2semodule/src/org/netbeans/modules/java/j2semodule/ui/customizer/Bundle.properties b/java/java.j2semodule/src/org/netbeans/modules/java/j2semodule/ui/customizer/Bundle.properties
index 078a809..aa60c2c 100644
--- a/java/java.j2semodule/src/org/netbeans/modules/java/j2semodule/ui/customizer/Bundle.properties
+++ b/java/java.j2semodule/src/org/netbeans/modules/java/j2semodule/ui/customizer/Bundle.properties
@@ -601,7 +601,7 @@
 ACSD_jButtonEdit=Edit classpath items
 ACSD_BuildJarAfterCompile=Build JAR after compiling option
 LBL_CustomizeRun_Enable_Quick_Run=Enable Quick Run
-CustomizerCompile.CompileOnSave=Compile on &Save
+CustomizerCompile.CompileOnSave=Compile on &Save (requires nb-javac plugin)
 AD_CustomizerCompile.CompileOnSave=If selected, files are compiled when you save them. This option saves you time when you run or debug your application in the IDE.
 LBL_CompileOnSaveDescription=<html>If selected, files are compiled when you save them.<br>\
     This option saves you time when you run or debug your application in the IDE.<br>\
diff --git a/java/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/customizer/Bundle.properties b/java/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/customizer/Bundle.properties
index acf0a8a..9cb2102 100644
--- a/java/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/customizer/Bundle.properties
+++ b/java/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/customizer/Bundle.properties
@@ -601,7 +601,7 @@
 ACSD_jButtonEdit=Edit classpath items
 ACSD_BuildJarAfterCompile=Build JAR after compiling option
 LBL_CustomizeRun_Enable_Quick_Run=Enable Quick Run
-CustomizerCompile.CompileOnSave=Compile on &Save
+CustomizerCompile.CompileOnSave=Compile on &Save (requires nb-javac plugin)
 AD_CustomizerCompile.CompileOnSave=If selected, files are compiled when you save them. This option saves you time when you run or debug your application in the IDE.
 LBL_CompileOnSaveDescription=<html>If selected, files are compiled when you save them.<br>\
     This option saves you time when you run or debug your application in the IDE.<br>\
diff --git a/java/java.source.base/src/org/netbeans/modules/java/source/parsing/CachingFileManager.java b/java/java.source.base/src/org/netbeans/modules/java/source/parsing/CachingFileManager.java
index 294be61..eb64f36 100644
--- a/java/java.source.base/src/org/netbeans/modules/java/source/parsing/CachingFileManager.java
+++ b/java/java.source.base/src/org/netbeans/modules/java/source/parsing/CachingFileManager.java
@@ -247,6 +247,8 @@
                 Archive archive = provider.getArchive( entry.getURL(), cacheFile );
                 if (archive != null) {
                     final Iterable<JavaFileObject> entries;
+                    // multi-release code here duplicated in ModuleFileManager
+                    // fixes should be ported across, or ideally this logic abstracted
                     if (supportsMultiRelease && archive.isMultiRelease()) {
                         if (prefixes == null) {
                             prefixes = multiReleaseRelocations();
@@ -267,11 +269,12 @@
                                 }
                                 final String fqn = inferBinaryName(l, fo);
                                 final String pkg = FileObjects.getPackageAndName(fqn)[0];
+                                final String name = pkg + "/" + FileObjects.getName(fo, false);
                                 if (base) {
                                     seenPackages.add(pkg);
-                                    fqn2f.put(fqn, fo);
+                                    fqn2f.put(name, fo);
                                 } else if (seenPackages.contains(pkg)) {
-                                    fqn2f.put(fqn, fo);
+                                    fqn2f.put(name, fo);
                                 }
                             }
                         }
diff --git a/java/java.source.base/src/org/netbeans/modules/java/source/parsing/ModuleFileManager.java b/java/java.source.base/src/org/netbeans/modules/java/source/parsing/ModuleFileManager.java
index 914face..dea019c 100644
--- a/java/java.source.base/src/org/netbeans/modules/java/source/parsing/ModuleFileManager.java
+++ b/java/java.source.base/src/org/netbeans/modules/java/source/parsing/ModuleFileManager.java
@@ -100,6 +100,8 @@
                 final Archive archive = cap.getArchive(root, cacheFile);
                 if (archive != null) {
                     final Iterable<JavaFileObject> entries;
+                    // multi-release code here duplicated in CachingFileManager
+                    // fixes should be ported across, or ideally this logic abstracted
                     if (supportsMultiRelease && archive.isMultiRelease()) {
                         if (prefixes == null) {
                             prefixes = multiReleaseRelocations();
@@ -120,11 +122,12 @@
                                 }
                                 final String fqn = inferBinaryName(l, fo);
                                 final String pkg = FileObjects.getPackageAndName(fqn)[0];
+                                final String name = pkg + "/" + FileObjects.getName(fo, false);
                                 if (base) {
                                     seenPackages.add(pkg);
-                                    fqn2f.put(fqn, fo);
+                                    fqn2f.put(name, fo);
                                 } else if (seenPackages.contains(pkg)) {
-                                    fqn2f.put(fqn, fo);
+                                    fqn2f.put(name, fo);
                                 }
                             }
                         }
diff --git a/java/java.source.base/src/org/netbeans/modules/java/source/save/Reformatter.java b/java/java.source.base/src/org/netbeans/modules/java/source/save/Reformatter.java
index 916ac4f..799e173 100644
--- a/java/java.source.base/src/org/netbeans/modules/java/source/save/Reformatter.java
+++ b/java/java.source.base/src/org/netbeans/modules/java/source/save/Reformatter.java
@@ -2864,6 +2864,7 @@
             if(statements != null)
             accept(COLON);
             else {
+                space();
                 accept(ARROW);
                 caseBody = TreeShims.getBody(node);
                 if (caseBody instanceof StatementTree)
@@ -3468,8 +3469,6 @@
                             ? getIndent()
                             : after == 2 //after javadoc comment
                             ? getNewlines(1) + getIndent()
-                            : id == ARROW
-                            ? SPACE
                             : null;
                     if (lastWSToken != null) {
                         if (spaces == null || !spaces.contentEquals(lastWSToken.text()))
diff --git a/java/java.source.base/test/unit/src/org/netbeans/modules/java/source/save/FormatingTest.java b/java/java.source.base/test/unit/src/org/netbeans/modules/java/source/save/FormatingTest.java
index 613864a..fa1fd2e 100644
--- a/java/java.source.base/test/unit/src/org/netbeans/modules/java/source/save/FormatingTest.java
+++ b/java/java.source.base/test/unit/src/org/netbeans/modules/java/source/save/FormatingTest.java
@@ -46,6 +46,7 @@
 import org.netbeans.modules.java.JavaDataLoader;
 import org.netbeans.modules.java.source.BootClassPathUtil;
 import org.netbeans.modules.java.source.usages.IndexUtil;
+import org.netbeans.modules.java.ui.FmtOptions;
 import org.netbeans.spi.java.classpath.ClassPathProvider;
 import org.netbeans.spi.java.classpath.support.ClassPathSupport;
 import org.openide.cookies.EditorCookie;
@@ -4830,7 +4831,18 @@
                 + "        java.util.Arrays.asList(args).map((val) -> val.length());\n"
                 + "    }\n"
                 + "}\n";
+        // Testing with wrapping lambda arrow deactivated
         reformat(doc, content, golden);
+
+        final String wrapAfterLambdaArrow = FmtOptions.wrapAfterLambdaArrow;
+        Preferences preferences = MimeLookup.getLookup(JavaTokenId.language().mimeType()).lookup(Preferences.class);
+        preferences.putBoolean(wrapAfterLambdaArrow, true);
+
+        // Testing with wrapping lambda arrow activated
+        reformat(doc, content, golden);
+
+        // Returning the setting to the default value
+        preferences.putBoolean(wrapAfterLambdaArrow, FmtOptions.getDefaultAsBoolean(wrapAfterLambdaArrow));
     }
 
     public void testForNoCondition() throws Exception {
diff --git a/java/java.source/src/org/netbeans/modules/java/source/JBrowseModule.java b/java/java.source/src/org/netbeans/modules/java/source/JBrowseModule.java
index 65d798b..cfaa44d 100644
--- a/java/java.source/src/org/netbeans/modules/java/source/JBrowseModule.java
+++ b/java/java.source/src/org/netbeans/modules/java/source/JBrowseModule.java
@@ -22,6 +22,7 @@
 import java.awt.Dialog;
 import java.awt.GraphicsEnvironment;
 import java.util.prefs.Preferences;
+import javax.lang.model.SourceVersion;
 import org.netbeans.api.annotations.common.StaticResource;
 import org.netbeans.modules.autoupdate.ui.api.PluginManager;
 import org.netbeans.modules.java.source.usages.ClassIndexManager;
@@ -91,7 +92,7 @@
                     prefs.putBoolean(KEY_WARNING_SHOWN, true);
                 }
 
-                if (!NoJavacHelper.hasNbJavac()) {
+                if (!NoJavacHelper.hasNbJavac() && !hasJDK14OrAboveJavac()) {
                     NotificationDisplayer.getDefault().notify("Install nb-javac Library", ImageUtilities.loadImageIcon(WARNING_ICON, false), Bundle.DESC_InstallNbJavac(), evt -> {
                         PluginManager.installSingle("org.netbeans.modules.nbjavac", Bundle.DN_nbjavac());
                     }, prefs.getBoolean(KEY_WARNING_SHOWN, false) ? Priority.SILENT : Priority.HIGH);
@@ -102,6 +103,15 @@
         super.restored();
     }
 
+    private boolean hasJDK14OrAboveJavac() {
+        try {
+            SourceVersion.valueOf("RELEASE_14");
+            return true;
+        } catch (IllegalArgumentException ex) {
+            return false;
+        }
+    }
+
     @Override
     public void close () {
         super.close();
diff --git a/java/maven/src/org/netbeans/modules/maven/customizer/Bundle.properties b/java/maven/src/org/netbeans/modules/maven/customizer/Bundle.properties
index 35aa7a4..dfbd3d7 100644
--- a/java/maven/src/org/netbeans/modules/maven/customizer/Bundle.properties
+++ b/java/maven/src/org/netbeans/modules/maven/customizer/Bundle.properties
@@ -142,7 +142,7 @@
 RunJarPanel.lblConfiguration.text=&Configuration:
 ActionMappings.txtPackagings.text=
 ActionMappings.lblPackagings.text=Supported Packagings:
-CompilePanel.cbCompileOnSave.text=Compile On &Save
+CompilePanel.cbCompileOnSave.text=Compile on &Save (requires nb-javac plugin)
 CompilePanel.btnLearnMore.text=<html><a href="">Learn More about Compile On Save feature in Maven projects</a></html>
 ActionMappings.jButton1.text=Show in Toolbar
 RunJarPanel.txtVMOptions.AccessibleContext.accessibleDescription=VM options
diff --git a/java/spi.java.hints/src/org/netbeans/modules/java/hints/providers/spi/HintMetadata.java b/java/spi.java.hints/src/org/netbeans/modules/java/hints/providers/spi/HintMetadata.java
index e98893a..4b3651e 100644
--- a/java/spi.java.hints/src/org/netbeans/modules/java/hints/providers/spi/HintMetadata.java
+++ b/java/spi.java.hints/src/org/netbeans/modules/java/hints/providers/spi/HintMetadata.java
@@ -175,6 +175,7 @@
                     this.sourceVersion = SourceVersion.valueOf("RELEASE_" + version);
                 } catch (IllegalArgumentException ex) {
                     this.sourceVersion = SourceVersion.RELEASE_3;
+                    setEnabled(false);
                 }
             }
             return this;
diff --git a/nb/updatecenters/build.xml b/nb/updatecenters/build.xml
index b9a6577..f91f4c0 100644
--- a/nb/updatecenters/build.xml
+++ b/nb/updatecenters/build.xml
@@ -41,8 +41,6 @@
       />
       <subant  target="nbm" inheritall="false">
           <property name="build.dir" location="build/3rdparty-nbms"/>
-          <property name="keystore" location="${netbeans.bundled.ks}"/>
-          <property name="storepass" value="${netbeans.bundled.ks}"/>
           <property name="nbm_alias" value="netbeans-bundled"/>
           <fileset dir="${nb_all}/extra" includes="libs.javafx.*/build.xml"/>
       </subant>
@@ -56,8 +54,6 @@
       </subant>
       <subant target="nbm" inheritall="false">
           <property name="build.dir" location="build/3rdparty-nbms"/>
-          <property name="keystore" location="${netbeans.bundled.ks}"/>
-          <property name="storepass" value="${netbeans.bundled.ks}"/>
           <property name="nbm_alias" value="netbeans-bundled"/>
           <property name="nb_all" location="${nb_all}"/>
           <property name="nbplatform.default.netbeans.dest.dir" location="${netbeans.dest.dir}"/>
diff --git a/nb/updatecenters/extras/nbjavac/src/org/netbeans/modules/nbjavac/Bundle.properties b/nb/updatecenters/extras/nbjavac/src/org/netbeans/modules/nbjavac/Bundle.properties
index fdea444..9da78f6 100644
--- a/nb/updatecenters/extras/nbjavac/src/org/netbeans/modules/nbjavac/Bundle.properties
+++ b/nb/updatecenters/extras/nbjavac/src/org/netbeans/modules/nbjavac/Bundle.properties
@@ -16,4 +16,8 @@
 # under the License.
 
 OpenIDE-Module-Display-Category=Java
+OpenIDE-Module-Long-Description=\
+    This library improves the Java editor behavior and enables the Compile on Save features. \
+    Note this plugin does not support JDK 14 language features, like records.
 OpenIDE-Module-Name=The nb-javac Java editing support library
+OpenIDE-Module-Short-Description=The nb-javac Java editing support library
diff --git a/nb/updatecenters/src/org/netbeans/modules/updatecenters/resources/mf-layer.xml b/nb/updatecenters/src/org/netbeans/modules/updatecenters/resources/mf-layer.xml
index b57d7a8..bacad2f 100644
--- a/nb/updatecenters/src/org/netbeans/modules/updatecenters/resources/mf-layer.xml
+++ b/nb/updatecenters/src/org/netbeans/modules/updatecenters/resources/mf-layer.xml
@@ -62,6 +62,7 @@
           <attr name="url" bundlevalue="org.netbeans.modules.updatecenters.resources.Bundle#URL_3rdparty"/>
           <attr name="category" stringvalue="STANDARD"/>
           <attr name="enabled" boolvalue="true"/>
+          <attr name="trusted" boolvalue="true"/>
           <attr name="instanceOf" stringvalue="org.netbeans.spi.autoupdate.UpdateProvider"/>
           <attr name="instanceCreate" methodvalue="org.netbeans.modules.autoupdate.updateprovider.AutoupdateCatalogFactory.createUpdateProvider"/>
       </file>
diff --git a/platform/core.output2/src/org/netbeans/core/output2/NbIOProvider.java b/platform/core.output2/src/org/netbeans/core/output2/NbIOProvider.java
index 1b97732..dc02729 100644
--- a/platform/core.output2/src/org/netbeans/core/output2/NbIOProvider.java
+++ b/platform/core.output2/src/org/netbeans/core/output2/NbIOProvider.java
@@ -25,6 +25,7 @@
 import java.util.EnumSet;
 import java.util.Set;
 import java.util.WeakHashMap;
+import java.util.logging.Level;
 import javax.swing.Action;
 import org.netbeans.api.io.Hyperlink;
 import org.netbeans.api.io.OutputColor;
@@ -214,7 +215,14 @@
     @Override
     public void resetIO(InputOutput io) {
         if (io instanceof NbIO) {
-            ((NbIO) io).reset();
+            try {
+                // ((NbWriter)io.getOut).reset() does OutWriter fixup,
+                // then NbWriter invokes ((NbIO) io).reset()
+                io.getOut().reset();
+            } catch (IOException ex) {
+                Exceptions.attachSeverity(ex, Level.WARNING);
+                Exceptions.printStackTrace(ex);
+            }
         } else {
             throw new IllegalArgumentException();
         }
diff --git a/platform/core.output2/test/unit/src/org/netbeans/core/output2/LifecycleTest.java b/platform/core.output2/test/unit/src/org/netbeans/core/output2/LifecycleTest.java
index 48e3dcf..50e01d3 100644
--- a/platform/core.output2/test/unit/src/org/netbeans/core/output2/LifecycleTest.java
+++ b/platform/core.output2/test/unit/src/org/netbeans/core/output2/LifecycleTest.java
@@ -60,6 +60,7 @@
 
     private IOContainer container;
     private NbIO io;
+    private NbIOProvider ioProvider;
     JFrame jf = null;
 
     OutputTab tab = null;
@@ -75,7 +76,8 @@
                 jf.getContentPane().add(getIOWindow(), BorderLayout.CENTER);
                 jf.setBounds(20, 20, 700, 300);
                 jf.setVisible(true);
-                io = (NbIO) new NbIOProvider().getIO("Test", false);
+                ioProvider = new NbIOProvider();
+                io = (NbIO) ioProvider.getIO("Test", false);
                 io.select();
                 tab = (OutputTab) container.getSelected();
                 pane = (OutputPane) tab.getOutputPane();
@@ -99,6 +101,7 @@
         }
         io.closeInputOutput();
         io = null;
+        ioProvider = null;
         container = null;
         sleep();
     }
@@ -240,6 +243,45 @@
             "fetch its storage after it was disposed.  It appears it wasn't disposed.", e);
     }
 
+    /**
+     * org.netbeans.api.io.InputOutput uses InputOutput.reset(),
+     * NOT writer.reset().[NETBEANS-4203]
+     * <p>
+     * Identical to testReset, expcept use ioProvider.resetIO(io) not writer.reset()
+     * </p>
+     * @throws Exception 
+     */
+    public void testNbIOReset() throws Exception {
+        System.out.println("testNbIOReset");
+        ErrWriter err = io.writer().getErr();
+        OutWriter out = io.writer().out();
+        NbWriter writer = io.writer();
+
+        OutputDocument doc = (OutputDocument) pane.getDocument();
+        assertNotNull ("Document should not be null", doc);
+
+        err.println ("hello");
+        writer.println ("world");
+        sleep();
+        ioProvider.resetIO(io);
+        sleep();
+
+        assertTrue ("Same writer object should be used after a reset", io.writer() == writer);
+        assertTrue ("Same err object should be used after a reset", io.writer().err() == err);
+        assertTrue ("Different output should be used afer a reset", out != io.writer().out());
+
+        assertNull ("Old document's Lines object not disposed - that means neither was its writer", doc.getLines());
+
+        Exception e = null;
+        try {
+            out.getStorage();
+        } catch (Exception exc) {
+            e = exc;
+        }
+        assertNotNull ("OutWriter should have thrown an exception on trying to " +
+            "fetch its storage after it was disposed.  It appears it wasn't disposed.", e);
+    }
+
     public void testCloseInputOutput() throws Exception {
 
         System.out.println("testCloseInputOutput");
diff --git a/webcommon/javascript.nodejs/samples_src/MessagesAngular/package.json b/webcommon/javascript.nodejs/samples_src/MessagesAngular/package.json
index ea851f1..877fc23 100644
--- a/webcommon/javascript.nodejs/samples_src/MessagesAngular/package.json
+++ b/webcommon/javascript.nodejs/samples_src/MessagesAngular/package.json
@@ -10,7 +10,7 @@
     "dependencies": {
         "express": "^4.10.1",
         "body-parser": "^1.4.3",
-        "bower": "~1.3.12"
+        "bower": "~1.8.8"
     },
     "devDependencies": {
         "gulp": "^3.8.10",
diff --git a/webcommon/javascript.nodejs/samples_src/MessagesExpress/package.json b/webcommon/javascript.nodejs/samples_src/MessagesExpress/package.json
index 5664cdf..accbe7e 100644
--- a/webcommon/javascript.nodejs/samples_src/MessagesExpress/package.json
+++ b/webcommon/javascript.nodejs/samples_src/MessagesExpress/package.json
@@ -11,11 +11,11 @@
     "dependencies": {
         "body-parser": "~1.10.2",
         "cookie-parser": "~1.3.3",
-        "debug": "~2.1.1",
+        "debug": "~2.6.9",
         "express": "~4.11.1",
         "jade": "~1.9.1",
-        "morgan": "~1.5.1",
-        "bower" : "~1.3.12"
+        "morgan": "~1.9.1",
+        "bower" : "~1.8.8"
     },
     "devDependencies": {
         "grunt": "^0.4.5",
diff --git a/webcommon/javascript.nodejs/samples_src/MessagesKnockout/package.json b/webcommon/javascript.nodejs/samples_src/MessagesKnockout/package.json
index d407fb3..40bbc89 100644
--- a/webcommon/javascript.nodejs/samples_src/MessagesKnockout/package.json
+++ b/webcommon/javascript.nodejs/samples_src/MessagesKnockout/package.json
@@ -6,7 +6,7 @@
     "dependencies": {
         "express": "^4.10.1",
         "body-parser": "^1.4.3",
-        "bower" : "~1.3.12"
+        "bower" : "~1.8.8"
     },
     "devDependencies": {
         "grunt": "^0.4.5",