[hg] main-silver: #196538 - Extend UI API for PM.openInstallWiza...

  • From: Petr Hejl < >
  • To: , , , ,
  • Subject: [hg] main-silver: #196538 - Extend UI API for PM.openInstallWiza...
  • Date: Wed, 13 Feb 2013 04:45:12 -0800

changeset 35ee4100701e in main-silver ((none))
details: http://hg.netbeans.org/main-silver/rev/35ee4100701e
description:
        #196538 - Extend UI API for PM.openInstallWizard(String... 
codeNameBase)

diffstat:

 autoupdate.ui/apichanges.xml                                                 
              |   21 +
 autoupdate.ui/manifest.mf                                                    
              |    2 +-
 autoupdate.ui/nbproject/project.xml                                          
              |    9 +
 
autoupdate.ui/src/org/netbeans/modules/autoupdate/ui/ModuleInstallerSupport.java
           |  417 ++++++++++
 autoupdate.ui/src/org/netbeans/modules/autoupdate/ui/api/PluginManager.java  
              |   87 ++
 code.analysis/manifest.mf                                                    
              |    2 +-
 code.analysis/nbproject/project.xml                                          
              |   10 +-
 code.analysis/src/org/netbeans/modules/analysis/ModuleInstallerSupport.java  
              |  330 -------
 code.analysis/src/org/netbeans/modules/analysis/Utils.java                   
              |    8 +-
 findbugs.installer/manifest.mf                                               
              |    2 +-
 findbugs.installer/nbproject/project.xml                                     
              |   10 +-
 
findbugs.installer/src/org/netbeans/modules/findbugs/installer/FindBugsPanel.java
          |    7 +-
 
findbugs.installer/src/org/netbeans/modules/findbugs/installer/ModuleInstallerSupport.java
 |  331 -------
 junit/manifest.mf                                                            
              |    2 +-
 junit/nbproject/project.xml                                                  
              |   10 +-
 junit/src/org/netbeans/modules/junit/JUnitLibraryDownloader.java             
              |  307 +-------
 16 files changed, 554 insertions(+), 1001 deletions(-)

diffs (1786 lines):

diff --git a/autoupdate.ui/apichanges.xml b/autoupdate.ui/apichanges.xml
--- a/autoupdate.ui/apichanges.xml
+++ b/autoupdate.ui/apichanges.xml
@@ -56,6 +56,27 @@
     <!-- ACTUAL CHANGES BEGIN HERE: -->
 
     <changes>
+        <change id="PluginManager.installPlugins">
+            <api name="ui"/>
+            <summary>PluginManager.install</summary>
+            <version major="1" minor="35"/>
+            <date day="13" month="2" year="2013"/>
+            <author login="phejl"/>
+            <compatibility addition="yes" binary="compatible" deletion="no"
+                deprecation="no" semantic="compatible" source="compatible"
+            />
+            <description>
+                <p>
+                <code>PluginManager</code> ands its
+                <a 
href="@TOP@/org/netbeans/modules/autoupdate/ui/api/PluginManager.html#installSingle(java.lang.String,
 java.lang.String, java.lang.Object[])">installSingle</a>
+                and <a 
href="@TOP@/org/netbeans/modules/autoupdate/ui/api/PluginManager.html#install(java.util.Set,
 java.lang.Object[])">install</a>
+                shows standard UI for easy installation of single plugin 
based
+                on codenamebase.
+                </p>
+            </description>
+            <class package="org.netbeans.modules.autoupdate.ui.api" 
name="PluginManager"/>
+            <issue number="196538"/>
+        </change>
         <change id="PluginManager.openInstallWizard">
             <api name="ui"/>
             <summary>PluginManager.openInstallWizard</summary>
diff --git a/autoupdate.ui/manifest.mf b/autoupdate.ui/manifest.mf
--- a/autoupdate.ui/manifest.mf
+++ b/autoupdate.ui/manifest.mf
@@ -2,6 +2,6 @@
 OpenIDE-Module: org.netbeans.modules.autoupdate.ui
 OpenIDE-Module-Install: 
org/netbeans/modules/autoupdate/ui/actions/Installer.class
 OpenIDE-Module-Localizing-Bundle: 
org/netbeans/modules/autoupdate/ui/resources/Bundle.properties
-OpenIDE-Module-Specification-Version: 1.34
+OpenIDE-Module-Specification-Version: 1.35
 AutoUpdate-Show-In-Client: false
 AutoUpdate-Essential-Module: true
diff --git a/autoupdate.ui/nbproject/project.xml 
b/autoupdate.ui/nbproject/project.xml
--- a/autoupdate.ui/nbproject/project.xml
+++ b/autoupdate.ui/nbproject/project.xml
@@ -6,6 +6,15 @@
             
<code-name-base>org.netbeans.modules.autoupdate.ui</code-name-base>
             <module-dependencies>
                 <dependency>
+                    
<code-name-base>org.netbeans.api.annotations.common</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>1</release-version>
+                        <specification-version>1.19</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
                     
<code-name-base>org.netbeans.api.progress</code-name-base>
                     <build-prerequisite/>
                     <compile-dependency/>
diff --git 
a/autoupdate.ui/src/org/netbeans/modules/autoupdate/ui/ModuleInstallerSupport.java
 
b/autoupdate.ui/src/org/netbeans/modules/autoupdate/ui/ModuleInstallerSupport.java
new file mode 100644
--- /dev/null
+++ 
b/autoupdate.ui/src/org/netbeans/modules/autoupdate/ui/ModuleInstallerSupport.java
@@ -0,0 +1,417 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License.  When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2013 Sun Microsystems, Inc.
+ */
+package org.netbeans.modules.autoupdate.ui;
+
+import java.awt.Dialog;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import org.netbeans.api.autoupdate.InstallSupport;
+import org.netbeans.api.autoupdate.OperationContainer;
+import org.netbeans.api.autoupdate.OperationException;
+import org.netbeans.api.autoupdate.OperationSupport;
+import org.netbeans.api.autoupdate.OperationSupport.Restarter;
+import org.netbeans.api.autoupdate.UpdateElement;
+import org.netbeans.api.autoupdate.UpdateManager;
+import org.netbeans.api.autoupdate.UpdateUnit;
+import org.netbeans.api.autoupdate.UpdateUnitProvider;
+import org.netbeans.api.autoupdate.UpdateUnitProviderFactory;
+import org.netbeans.api.options.OptionsDisplayer;
+import org.netbeans.api.progress.ProgressHandle;
+import org.netbeans.api.progress.ProgressHandleFactory;
+import org.netbeans.modules.autoupdate.ui.api.PluginManager;
+import org.openide.DialogDescriptor;
+import org.openide.DialogDisplayer;
+import org.openide.NotifyDescriptor;
+import org.openide.awt.Mnemonics;
+import org.openide.util.NbBundle.Messages;
+import org.openide.util.RequestProcessor;
+import static org.netbeans.modules.autoupdate.ui.Bundle.*;
+
+/**
+ *
+ * @author Jesse Glick
+ * @author Jan Lahoda
+ * @author Petr Hejl
+ */
+public class ModuleInstallerSupport  {
+    private static RequestProcessor RP = new 
RequestProcessor(ModuleInstallerSupport.class.getName(), 1);
+    private static final Logger LOG = 
Logger.getLogger(ModuleInstallerSupport.class.getName());
+
+    @Messages({
+        "searching_handle_single=Searching for \"{0}\" module on NetBeans 
plugin portal...",
+        "resolve_title_single=Resolve \"{0}\" Reference Problem",
+        "nodownload_header_single=\"{0}\" module has not been downloaded",
+        "nodownload_message_single=You can try to download \"{0}\" module 
again",
+        "active_handle_single=Activating {0}",
+
+        "searching_handle=Searching for modules on NetBeans plugin 
portal...",
+        "resolve_title=Resolve Reference Problem",
+        "nodownload_header=Modules have not been downloaded",
+        "nodownload_message=You can try to download modules again",
+        "active_handle=Activating modules",
+
+        "networkproblem_header=Unable to connect  to the NetBeans plugin 
portal",
+        "networkproblem_message=Check your proxy settings or try again 
later. "
+            + "The server may be unavailable at the moment. "
+            + "You may also want to make sure that your firewall is not 
blocking network traffic.",
+        "proxy_button=&Proxy Settings...",
+        "tryagain_button=Try &Again"
+    })
+
+    private final Object[] closingOptions;
+
+    private Object[] fullClosingOptions;
+    private JButton tryAgain;
+    private JButton proxySettings;
+
+    public ModuleInstallerSupport(Object... alternativeOptions) {
+        this.closingOptions = alternativeOptions.clone();
+    }
+
+    public Object installPlugins(final String displayName, Set<String> cnbs) 
throws OperationException {
+        Collection<UpdateUnit> units = findModules(cnbs);
+        if (units == null) {
+            final String searchMessage = displayName != null
+                    ? searching_handle_single(displayName) : 
searching_handle();
+            final String resolveTitle = displayName != null
+                    ? resolve_title_single(displayName) : resolve_title();
+
+            final ProgressHandle handle = 
ProgressHandleFactory.createHandle(searchMessage);
+            initButtons();
+            final DialogDescriptor searching = new 
DialogDescriptor(searchingPanel(new JLabel(searchMessage),
+                    ProgressHandleFactory.createProgressComponent(handle)), 
resolveTitle, true, null);
+            handle.setInitialDelay(0);
+            handle.start();
+            searching.setOptions(new Object[] 
{NotifyDescriptor.CANCEL_OPTION});
+            searching.setMessageType(NotifyDescriptor.PLAIN_MESSAGE);
+            final Dialog dlg = 
DialogDisplayer.getDefault().createDialog(searching);
+            RP.post(new Runnable() {
+
+                @Override
+                public void run() {
+                    // May be first start, when no update lists have yet 
been downloaded.
+                    try {
+                        for (UpdateUnitProvider p : 
UpdateUnitProviderFactory.getDefault().getUpdateUnitProviders(true)) {
+                            p.refresh(handle, true);
+                        }
+                        // close searching
+                        dlg.dispose();
+                    } catch (IOException ex) {
+                        LOG.log(Level.FINE, ex.getMessage(), ex);
+                        if (!dlg.isVisible()) {
+                            LOG.fine("dialog not visible => do nothing");
+                            return;
+                        }
+                        DialogDescriptor networkProblem = new 
DialogDescriptor(
+                                problemPanel(resolveTitle, 
networkproblem_message()), // message
+                                networkproblem_header(), // title
+                                true, // modal
+                                null);
+                        networkProblem.setOptions(new Object[] {tryAgain, 
proxySettings, NotifyDescriptor.CANCEL_OPTION});
+                        networkProblem.setAdditionalOptions(closingOptions);
+                        networkProblem.setClosingOptions(fullClosingOptions);
+                        
networkProblem.setMessageType(NotifyDescriptor.WARNING_MESSAGE);
+                        Dialog networkProblemDialog = 
DialogDisplayer.getDefault().createDialog(networkProblem);
+                        networkProblemDialog.setVisible(true);
+                        Object answer = networkProblem.getValue();
+                        if (NotifyDescriptor.CANCEL_OPTION.equals(answer)
+                                || 
Arrays.asList(closingOptions).contains(answer)
+                                || 
answer.equals(NotifyDescriptor.DEFAULT_OPTION) /* escape */ ) {
+                            LOG.fine("cancel network problem dialog");
+                            searching.setValue(answer);
+                            dlg.dispose();
+                        } else if (tryAgain.equals(answer)) {
+                            LOG.fine("try again searching");
+                            RP.post(this);
+                        } else {
+                            assert false : "Unknown " + answer;
+                        }
+                    }
+                }
+            });
+            dlg.setVisible(true);
+            handle.finish();
+            if (NotifyDescriptor.CANCEL_OPTION.equals(searching.getValue())
+                    || 
searching.getValue().equals(NotifyDescriptor.DEFAULT_OPTION) /* escape */) {
+                LOG.log(Level.FINE, "user canceled searching for {0}", cnbs);
+                return showNoDownloadDialog(displayName, cnbs);
+            } else if 
(Arrays.asList(closingOptions).contains(searching.getValue())){
+                return searching.getValue();
+            }
+            units = findModules(cnbs);
+            if (units == null) {
+                LOG.log(Level.FINE, "could not find {0} on any update site", 
cnbs);
+                return showNoDownloadDialog(displayName, cnbs);
+            }
+        }
+
+        List<UpdateUnit> toHandle = new ArrayList<UpdateUnit>(units);
+        OperationContainer<OperationSupport> oc = null;
+
+        for (Iterator<UpdateUnit> it = toHandle.iterator(); it.hasNext(); ) {
+            UpdateUnit unit = it.next();
+
+            // check if module installed
+            if (unit.getInstalled() != null) {
+                if (LOG.isLoggable(Level.FINE)) {
+                    LOG.fine(unit.getInstalled() + " already installed. Is 
active? " + unit.getInstalled().isEnabled());
+                }
+                if (unit.getInstalled().isEnabled()) {
+                    it.remove();
+                    continue;
+                } else {
+                    if (oc == null) {
+                        oc = OperationContainer.createForEnable();
+                    }
+                    if (!oc.canBeAdded(unit, unit.getInstalled())) {
+                        throw new 
OperationException(OperationException.ERROR_TYPE.ENABLE,
+                                "could not add " + unit.getInstalled() + " 
for activation");
+                    }
+                    for (UpdateElement req : 
oc.add(unit.getInstalled()).getRequiredElements()) {
+                        oc.add(req);
+                    }
+                    it.remove();
+                    continue;
+                }
+            }
+        }
+
+        if (oc != null) {
+            ProgressHandle activeHandle = ProgressHandleFactory.createHandle(
+                    displayName != null ? active_handle_single(displayName) 
: active_handle());
+            Restarter restarter = oc.getSupport().doOperation(activeHandle);
+            assert restarter == null : "No Restater need to make units 
active";
+        }
+
+        if (toHandle.isEmpty()) {
+            return null;
+        }
+
+        OperationContainer<InstallSupport> ocInstall = 
OperationContainer.createForInstall();
+        for (Iterator<UpdateUnit> it = toHandle.iterator(); it.hasNext(); ) {
+            UpdateUnit unit = it.next();
+
+            List<UpdateElement> updates = unit.getAvailableUpdates();
+            if (updates.isEmpty()) {
+                throw new 
OperationException(OperationException.ERROR_TYPE.INSTALL, "no updates for " + 
unit);
+            }
+
+            UpdateElement element = updates.get(0);
+            if (!ocInstall.canBeAdded(unit, element)) {
+                throw new 
OperationException(OperationException.ERROR_TYPE.INSTALL, "could not add " + 
element + " to updates");
+            }
+            for (UpdateElement req : 
ocInstall.add(element).getRequiredElements()) {
+                ocInstall.add(req);
+            }
+            it.remove();
+        }
+        assert toHandle.isEmpty() : "These unit were not handled " + 
toHandle;
+
+        if (!PluginManager.openInstallWizard(ocInstall)) {
+            LOG.fine("user canceled PM");
+            return showNoDownloadDialog(displayName, cnbs);
+        }
+        return null;
+    }
+
+    private Collection<UpdateUnit> findModules(Set<String> cnbs) {
+        List<UpdateUnit> ret = new ArrayList<UpdateUnit>(cnbs.size());
+        for (UpdateUnit unit : 
UpdateManager.getDefault().getUpdateUnits(UpdateManager.TYPE.MODULE)) {
+            if (cnbs.contains(unit.getCodeName())) {
+                ret.add(unit);
+                if (ret.size() == cnbs.size()) {
+                    break;
+                }
+            }
+        }
+        if (ret.size() == cnbs.size()) {
+            return ret;
+        }
+        return null;
+    }
+
+    private void initButtons() {
+        if (tryAgain != null) {
+            return ;
+        }
+        tryAgain = new JButton();
+        proxySettings = new JButton();
+        Mnemonics.setLocalizedText(tryAgain, tryagain_button());
+        Mnemonics.setLocalizedText(proxySettings, proxy_button());
+        proxySettings.addActionListener(new ActionListener() {
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                LOG.fine("show proxy options");
+                OptionsDisplayer.getDefault().open("General"); // NOI18N
+            }
+        });
+        fullClosingOptions = new Object[closingOptions.length + 2];
+        System.arraycopy(closingOptions, 0, fullClosingOptions, 0, 
closingOptions.length);
+        fullClosingOptions[fullClosingOptions.length - 2] = tryAgain;
+        fullClosingOptions[fullClosingOptions.length - 1] = 
NotifyDescriptor.CANCEL_OPTION;
+    }
+
+    private Object showNoDownloadDialog(String displayName, Set<String> 
cnbs) throws OperationException {
+        DialogDescriptor networkProblem;
+        if (displayName != null) {
+            networkProblem = new DialogDescriptor(
+                    problemPanel(nodownload_header_single(displayName), 
nodownload_message_single(displayName)), // message
+                    resolve_title_single(displayName), // title
+                    true, // modal
+                    null);
+        } else {
+            networkProblem = new DialogDescriptor(
+                    problemPanel(nodownload_header(), nodownload_message()), 
// message
+                    resolve_title(), // title
+                    true, // modal
+                    null);
+        }
+        initButtons();
+        networkProblem.setOptions(new Object[] {tryAgain, 
NotifyDescriptor.CANCEL_OPTION});
+        networkProblem.setAdditionalOptions(closingOptions);
+        networkProblem.setClosingOptions(fullClosingOptions);
+        networkProblem.setMessageType(NotifyDescriptor.WARNING_MESSAGE);
+        Dialog networkProblemDialog = 
DialogDisplayer.getDefault().createDialog(networkProblem);
+        networkProblemDialog.setVisible(true);
+        Object answer = networkProblem.getValue();
+        if (NotifyDescriptor.CANCEL_OPTION.equals(answer)
+                || Arrays.asList(closingOptions).contains(answer)
+                || answer.equals(NotifyDescriptor.DEFAULT_OPTION) /* escape 
*/ ) {
+            LOG.fine("cancel no download dialog");
+            //throw new InterruptedException("user canceled download & 
install JUnit");
+            return answer;
+        } else if (tryAgain.equals(answer)) {
+            LOG.fine("try again download()");
+            return installPlugins(displayName, cnbs);
+        } else {
+            assert false : "Unknown " + answer;
+        }
+        assert false : "Unknown " + answer;
+        return NotifyDescriptor.DEFAULT_OPTION;
+    }
+
+    private static JPanel searchingPanel(JLabel progressLabel, JComponent 
progressComponent) {
+        JPanel panel = new JPanel();
+        progressLabel.setLabelFor(progressComponent);
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(panel);
+        panel.setLayout(layout);
+        layout.setHorizontalGroup(
+            
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addContainerGap()
+                
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+                    .addComponent(progressLabel, 
javax.swing.GroupLayout.Alignment.LEADING, 
javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, 
Short.MAX_VALUE)
+                    .addComponent(progressComponent, 
javax.swing.GroupLayout.Alignment.LEADING, 
javax.swing.GroupLayout.DEFAULT_SIZE, 399, Short.MAX_VALUE))
+                .addContainerGap())
+        );
+        layout.setVerticalGroup(
+            
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addGap(96, 96, 96)
+                .addComponent(progressLabel)
+                
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                .addComponent(progressComponent, 
javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, 
javax.swing.GroupLayout.PREFERRED_SIZE)
+                .addContainerGap(109, Short.MAX_VALUE))
+        );
+        return panel;
+    }
+
+    private static JPanel problemPanel(String header, String message) {
+        JPanel panel = new JPanel();
+        JLabel jLabel1 = new javax.swing.JLabel();
+        JScrollPane jScrollPane1 = new javax.swing.JScrollPane();
+        JTextArea jTextArea1 = new javax.swing.JTextArea();
+
+        
jLabel1.setFont(jLabel1.getFont().deriveFont(jLabel1.getFont().getStyle() | 
java.awt.Font.BOLD));
+        jLabel1.setText(header);
+
+        jTextArea1.setColumns(20);
+        jTextArea1.setEditable(false);
+        jTextArea1.setLineWrap(true);
+        jTextArea1.setWrapStyleWord(true);
+        jTextArea1.setRows(5);
+        jTextArea1.setText(message);
+        jTextArea1.setOpaque(false);
+        jScrollPane1.setViewportView(jTextArea1);
+
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(panel);
+        panel.setLayout(layout);
+        layout.setHorizontalGroup(
+            
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addContainerGap()
+                
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addComponent(jScrollPane1, 
javax.swing.GroupLayout.DEFAULT_SIZE, 478, Short.MAX_VALUE)
+                    .addGroup(layout.createSequentialGroup()
+                        .addComponent(jLabel1)
+                        .addGap(107, 107, 107)))
+                .addContainerGap())
+        );
+        layout.setVerticalGroup(
+            
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addContainerGap()
+                .addComponent(jLabel1)
+                
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                .addComponent(jScrollPane1, 
javax.swing.GroupLayout.DEFAULT_SIZE, 133, Short.MAX_VALUE)
+                .addGap(82, 82, 82))
+        );
+        return panel;
+    }
+
+}
+
diff --git 
a/autoupdate.ui/src/org/netbeans/modules/autoupdate/ui/api/PluginManager.java 
b/autoupdate.ui/src/org/netbeans/modules/autoupdate/ui/api/PluginManager.java
--- 
a/autoupdate.ui/src/org/netbeans/modules/autoupdate/ui/api/PluginManager.java
+++ 
b/autoupdate.ui/src/org/netbeans/modules/autoupdate/ui/api/PluginManager.java
@@ -42,14 +42,25 @@
 
 package org.netbeans.modules.autoupdate.ui.api;
 
+import java.util.Collections;
 import java.util.List;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.netbeans.api.annotations.common.CheckForNull;
+import org.netbeans.api.annotations.common.NonNull;
 import org.netbeans.api.autoupdate.InstallSupport;
 import org.netbeans.api.autoupdate.OperationContainer;
 import org.netbeans.api.autoupdate.OperationContainer.OperationInfo;
+import org.netbeans.api.autoupdate.OperationException;
 import org.netbeans.api.autoupdate.UpdateManager;
+import org.netbeans.api.autoupdate.UpdateUnit;
+import org.netbeans.modules.autoupdate.ui.ModuleInstallerSupport;
 import org.netbeans.modules.autoupdate.ui.wizards.InstallUnitWizard;
 import org.netbeans.modules.autoupdate.ui.wizards.InstallUnitWizardModel;
 import 
org.netbeans.modules.autoupdate.ui.wizards.OperationWizardModel.OperationType;
+import org.openide.NotifyDescriptor;
+import org.openide.util.Parameters;
 
 /** Access to UI features of PluginManager that can be useful in other 
modules
  * as well. 
@@ -67,6 +78,9 @@
      * (until the user clicks through), so either call from AWT dispatch 
thread
      * directly, or be sure you hold no locks and block no progress of other
      * threads to avoid deadlocks.
+     * <p>
+     * Single module installation can be handled easily by
+     * {@link #installSingle(java.lang.String, java.lang.String, 
java.lang.Object[])}.
 <pre>
 {@link OperationContainer}<InstallSupport> container = 
OperationContainer.createForInstall();
 for ({@link UpdateUnit} u : {@link 
UpdateManager#getUpdateUnits(org.netbeans.api.autoupdate.UpdateManager.TYPE[])
 UpdateManager.getDefault().getUpdateUnits(UpdateManager.TYPE.MODULE)}) {
@@ -83,6 +97,8 @@
      * @param container the container with list of modules for install
      * @return true if all the requested modules were successfullly 
installed, 
      *    false otherwise.
+     * @see #installSingle(java.lang.String, java.lang.String, 
java.lang.Object[])
+     * @see #install(java.util.Set, java.lang.Object[]) 
      */
     public static boolean 
openInstallWizard(OperationContainer<InstallSupport> container) {
         if (container == null) {
@@ -100,4 +116,75 @@
         OperationType doOperation = info.getUpdateUnit ().getInstalled () == 
null ? OperationType.INSTALL : OperationType.UPDATE;
         return new InstallUnitWizard ().invokeWizard (new 
InstallUnitWizardModel (doOperation, container), false);
     }
+
+    /** Open standard dialog for installing a module including declared 
dependencies.
+     * Shows it to the user, asks for confirmation, license acceptance, etc.
+     * The whole operation requires AWT dispatch thread access (to show the 
dialog)
+     * and blocks (until the user clicks through), so either call from AWT 
dispatch
+     * thread directly, or be sure you hold no locks and block no progress 
of other
+     * threads to avoid deadlocks.
+     *
+     * @param codenamebase the codenamebase of module to install
+     * @param displayName the display name of the module
+     * @param alternativeOptions alternative options possibly displayed in 
error
+     *             dialog user may choose if it is not possible to install 
the plugin;
+     *             if chosen the option is return value of this method
+     * @return <code>null</code> if the module has been successfully 
installed
+     *             and/or activated, otherwise it returns the options user 
has
+     *             selected in problem dialog, typically {@link 
NotifyDescriptor#DEFAULT_OPTION}
+     *             (on esc), {@link NotifyDescriptor#CANCEL_OPTION} or
+     *             any of <code>alternativeOptions</code>.
+     * @since 1.35
+     * @see #install(java.util.Set, java.lang.Object[]) 
+     */
+    @CheckForNull
+    public static Object installSingle(@NonNull String codenamebase, 
@NonNull String displayName,
+            @NonNull Object... alternativeOptions) {
+        Parameters.notNull("cnb", codenamebase);
+        Parameters.notNull("displayName", displayName);
+        Parameters.notNull("alternativeOptions", alternativeOptions);
+
+        try {
+            return new 
ModuleInstallerSupport(alternativeOptions).installPlugins(displayName, 
Collections.singleton(codenamebase));
+        } catch (OperationException ex) {
+            
Logger.getLogger(PluginManager.class.getName()).log(Level.WARNING, null, ex);
 }
+        return NotifyDescriptor.DEFAULT_OPTION;
+    }
+
+    /** Open standard dialog for installing modules including declared 
dependencies.
+     * Shows it to the user, asks for confirmation, license acceptance, etc.
+     * The whole operation requires AWT dispatch thread access (to show the 
dialog)
+     * and blocks (until the user clicks through), so either call from AWT 
dispatch
+     * thread directly, or be sure you hold no locks and block no progress 
of other
+     * threads to avoid deadlocks.
+     *
+     * @param codenamebases the codenamebases of modules to install; must 
contain at least
+     *             one codenamebase
+     * @param alternativeOptions alternative options possibly displayed in 
error
+     *             dialog user may choose if it is not possible to install 
the plugin;
+     *             if chosen the option is return value of this method
+     * @return <code>null</code> if all the requested modules have been 
successfully
+     *             installed and/or activated, otherwise it returns the 
options user has
+     *             selected in problem dialog, typically {@link 
NotifyDescriptor#DEFAULT_OPTION}
+     *             (on esc), {@link NotifyDescriptor#CANCEL_OPTION} or
+     *             any of <code>alternativeOptions</code>.
+     * @throws IllegalArgumentException if the <code>codenamebases</code> is 
empty
+     * @since 1.35
+     */
+    @CheckForNull
+    public static Object install(@NonNull Set<String> codenamebases, 
@NonNull Object... alternativeOptions) {
+        Parameters.notNull("cnb", codenamebases);
+        Parameters.notNull("alternativeOptions", alternativeOptions);
+        if (codenamebases.isEmpty()) {
+            throw new IllegalArgumentException("No plugins to install");
+        }
+
+        try {
+            return new 
ModuleInstallerSupport(alternativeOptions).installPlugins(null, 
codenamebases);
+        } catch (OperationException ex) {
+            
Logger.getLogger(PluginManager.class.getName()).log(Level.WARNING, null, ex);
+        }
+        return NotifyDescriptor.DEFAULT_OPTION;
+    }
+}
diff --git a/code.analysis/manifest.mf b/code.analysis/manifest.mf
--- a/code.analysis/manifest.mf
+++ b/code.analysis/manifest.mf
@@ -2,5 +2,5 @@
 OpenIDE-Module: org.netbeans.modules.code.analysis/0
 OpenIDE-Module-Localizing-Bundle: 
org/netbeans/modules/analysis/Bundle.properties
 OpenIDE-Module-Requires: org.openide.windows.WindowManager
-OpenIDE-Module-Specification-Version: 1.12
+OpenIDE-Module-Specification-Version: 1.13
 
diff --git a/code.analysis/nbproject/project.xml 
b/code.analysis/nbproject/project.xml
--- a/code.analysis/nbproject/project.xml
+++ b/code.analysis/nbproject/project.xml
@@ -33,19 +33,11 @@
                     </run-dependency>
                 </dependency>
                 <dependency>
-                    
<code-name-base>org.netbeans.modules.autoupdate.services</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>1.29</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
                     
<code-name-base>org.netbeans.modules.autoupdate.ui</code-name-base>
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>1.26</specification-version>
+                        <specification-version>1.35</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
diff --git 
a/code.analysis/src/org/netbeans/modules/analysis/ModuleInstallerSupport.java 
b/code.analysis/src/org/netbeans/modules/analysis/ModuleInstallerSupport.java
deleted file mode 100644
--- 
a/code.analysis/src/org/netbeans/modules/analysis/ModuleInstallerSupport.java
+++ /dev/null
@@ -1,330 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
- *
- * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
- * Other names may be trademarks of their respective owners.
- *
- * The contents of this file are subject to the terms of either the GNU
- * General Public License Version 2 only ("GPL") or the Common
- * Development and Distribution License("CDDL") (collectively, the
- * "License"). You may not use this file except in compliance with the
- * License. You can obtain a copy of the License at
- * http://www.netbeans.org/cddl-gplv2.html
- * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
- * specific language governing permissions and limitations under the
- * License.  When distributing the software, include this License Header
- * Notice in each file and include the License file at
- * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the GPL Version 2 section of the License file that
- * accompanied this code. If applicable, add the following below the
- * License Header, with the fields enclosed by brackets [] replaced by
- * your own identifying information:
- * "Portions Copyrighted [year] [name of copyright owner]"
- *
- * If you wish your version of this file to be governed by only the CDDL
- * or only the GPL Version 2, indicate your decision by adding
- * "[Contributor] elects to include this software in this distribution
- * under the [CDDL or GPL Version 2] license." If you do not indicate a
- * single choice of license, a recipient has the option to distribute
- * your version of this file under either the CDDL, the GPL Version 2 or
- * to extend the choice of license to its licensees as provided above.
- * However, if you add GPL Version 2 code and therefore, elected the GPL
- * Version 2 license, then the option applies only if the new code is
- * made subject to such option by the copyright holder.
- *
- * Contributor(s):
- *
- * Portions Copyrighted 2011 Sun Microsystems, Inc.
- */
-
-package org.netbeans.modules.analysis;
-
-import java.awt.event.ActionEvent;
-import org.netbeans.api.autoupdate.OperationSupport;
-import org.netbeans.api.autoupdate.OperationSupport.Restarter;
-import org.netbeans.api.options.OptionsDisplayer;
-import javax.swing.JButton;
-import javax.swing.JTextArea;
-import javax.swing.JPanel;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import java.awt.Dialog;
-import java.awt.event.ActionListener;
-import javax.swing.JComponent;
-import javax.swing.JLabel;
-import org.openide.DialogDisplayer;
-import java.io.IOException;
-import java.util.List;
-import javax.swing.JScrollPane;
-import org.netbeans.api.autoupdate.InstallSupport;
-import org.netbeans.api.autoupdate.OperationContainer;
-import org.netbeans.api.autoupdate.UpdateElement;
-import org.netbeans.api.autoupdate.UpdateManager;
-import org.netbeans.api.autoupdate.UpdateUnit;
-import org.netbeans.api.autoupdate.UpdateUnitProvider;
-import org.netbeans.api.autoupdate.UpdateUnitProviderFactory;
-import org.netbeans.api.progress.ProgressHandle;
-import org.netbeans.api.progress.ProgressHandleFactory;
-import org.netbeans.modules.autoupdate.ui.api.PluginManager;
-import org.openide.DialogDescriptor;
-import org.openide.NotifyDescriptor;
-import org.openide.awt.Mnemonics;
-import org.openide.util.NbBundle.Messages;
-import org.openide.util.RequestProcessor;
-import static org.netbeans.modules.analysis.Bundle.*;
-
-/**
- * Copied and adjusted from the JUnitLibraryDownloader
- */
-public class ModuleInstallerSupport  {
-    private static RequestProcessor RP = new 
RequestProcessor(ModuleInstallerSupport.class.getName(), 1);
-    private static final Logger LOG = 
Logger.getLogger(ModuleInstallerSupport.class.getName());
-
-    @Messages({
-        "searching_handle=Searching for \"{0}\" library on NetBeans plugin 
portal...",
-        "resolve_title=Resolve \"{0}\" Reference Problem",
-        "networkproblem_header=Unable to connect  to the NetBeans plugin 
portal",
-        "networkproblem_message=Check your proxy settings or try again 
later. "
-            + "The server may be unavailable at the moment. "
-            + "You may also want to make sure that your firewall is not 
blocking network traffic.",
-        "proxy_button=&Proxy Settings...",
-        "tryagain_button=Try &Again",
-        "nodownload_header=\"{0}\" module has not been downloaded",
-        "nodownload_message=You can try to download \"{0}\" module again",
-        "active_handle=Activating {0}"
-    })
-    
-    private JButton tryAgain;
-    private JButton proxySettings;
-
-    @SuppressWarnings("SleepWhileInLoop")
-    public boolean download(String cnb, final String displayName) throws 
Exception {
-        UpdateUnit unit = findModule(cnb);
-        if (unit == null) {
-            final ProgressHandle handle = 
ProgressHandleFactory.createHandle(searching_handle(displayName));
-            initButtons();
-            final DialogDescriptor searching = new 
DialogDescriptor(searchingPanel(new JLabel(searching_handle(displayName)),
-                    ProgressHandleFactory.createProgressComponent(handle)), 
resolve_title(displayName), true, null);
-            handle.setInitialDelay (0);
-            handle.start ();
-            searching.setOptions(new Object[] 
{NotifyDescriptor.CANCEL_OPTION});
-            searching.setMessageType(NotifyDescriptor.PLAIN_MESSAGE);
-            final Dialog dlg = 
DialogDisplayer.getDefault().createDialog(searching);
-            RP.post(new Runnable() {
-
-                @Override
-                public void run() {
-                    // May be first start, when no update lists have yet 
been downloaded.
-                    try {
-                        for (UpdateUnitProvider p : 
UpdateUnitProviderFactory.getDefault().getUpdateUnitProviders(true)) {
-                            p.refresh(handle, true);
-                        }
-                        // close searching
-                        dlg.dispose();
-                    } catch (IOException ex) {
-                        LOG.log(Level.FINE, ex.getMessage(), ex);
-                        if (! dlg.isVisible()) {
-                            LOG.fine("dialog not visible => do nothing");
-                            return ;
-                        }
-                        DialogDescriptor networkProblem = new 
DialogDescriptor(
-                                problemPanel(resolve_title(displayName), 
networkproblem_message()), // message
-                                networkproblem_header(), // title
-                                true, // modal
-                                null);
-                        networkProblem.setOptions(new Object[] {tryAgain, 
proxySettings, NotifyDescriptor.CANCEL_OPTION});
-                        networkProblem.setClosingOptions(new Object[] 
{tryAgain, NotifyDescriptor.CANCEL_OPTION});
-                        
networkProblem.setMessageType(NotifyDescriptor.WARNING_MESSAGE);
-                        Dialog networkProblemDialog = 
DialogDisplayer.getDefault().createDialog(networkProblem);
-                        networkProblemDialog.setVisible(true);
-                        Object answer = networkProblem.getValue();
-                        if (NotifyDescriptor.CANCEL_OPTION.equals(answer) || 
answer.equals(-1) /* escape */ ) {
-                            LOG.fine("cancel network problem dialog");
-                            searching.setValue(answer);
-                            dlg.dispose();
-                        } else if (tryAgain.equals(answer)) {
-                            LOG.fine("try again searching");
-                            RP.post(this);
-                            assert false : "Unknown " + answer;
-                        }
-                    }
-                }
-            });
-            dlg.setVisible(true);
-            handle.finish();
-            if (NotifyDescriptor.CANCEL_OPTION.equals(searching.getValue()) 
|| searching.getValue().equals(-1) /* escape */) {
-                LOG.log(Level.FINE, "user canceled searching for {0}", cnb);
-                return showNoDownloadDialog(cnb, displayName);
-            }
-            unit = findModule(cnb);
-            if (unit == null) {
-                LOG.log(Level.FINE, "could not find {0} on any update site", 
cnb);
-                return showNoDownloadDialog(cnb, displayName);
-            }
-        }
-        // check if module installed
-        if (unit.getInstalled() != null) {
-            LOG.fine(unit.getInstalled() + " already installed. Is active? " 
+ unit.getInstalled().isEnabled());
-            if (unit.getInstalled().isEnabled()) {
-                throw new Exception(unit.getInstalled() + " already 
installed and active");
-            } else {
-                // activate it
-                OperationContainer<OperationSupport> oc = 
OperationContainer.createForEnable();
-                if (!oc.canBeAdded(unit, unit.getInstalled())) {
-                    throw new Exception("could not add " + 
unit.getInstalled() + " for activation");
-                }
-                for (UpdateElement req : 
oc.add(unit.getInstalled()).getRequiredElements()) {
-                    oc.add(req);
-                }
-                ProgressHandle activeHandle = 
ProgressHandleFactory.createHandle (active_handle(displayName));
-                Restarter restarter = 
oc.getSupport().doOperation(activeHandle);
-                assert restarter == null : "No Restater need to make " + 
unit.getInstalled() + " active";
-                // XXX new library & build.properties apparently do not show 
up immediately... how to listen properly?
-                return true;
-            }
-        }
-        List<UpdateElement> updates = unit.getAvailableUpdates();
-        if (updates.isEmpty()) {
-            throw new Exception("no updates for " + unit);
-        }
-        OperationContainer<InstallSupport> oc = 
OperationContainer.createForInstall();
-        UpdateElement element = updates.get(0);
-        if (!oc.canBeAdded(unit, element)) {
-            throw new Exception("could not add " + element + " to updates");
-        }
-        for (UpdateElement req : oc.add(element).getRequiredElements()) {
-            oc.add(req);
-        }
-        if (!PluginManager.openInstallWizard(oc)) {
-            LOG.fine("user canceled PM");
-            return showNoDownloadDialog(cnb, displayName);
-        }
-        return true;
-    }
-
-    private UpdateUnit findModule(String cnb) throws IOException {
-        for (UpdateUnit unit : 
UpdateManager.getDefault().getUpdateUnits(UpdateManager.TYPE.MODULE)) {
-            if (unit.getCodeName().equals(cnb)) {
-                return unit;
-            }
-        }
-        return null;
-    }
-    
-    private void initButtons() {
-        if (tryAgain != null) {
-            return ;
-        }
-        tryAgain = new JButton();
-        proxySettings = new JButton();
-        Mnemonics.setLocalizedText(tryAgain, tryagain_button());
-        Mnemonics.setLocalizedText(proxySettings, proxy_button());
-        proxySettings.addActionListener(new ActionListener() {
-            @Override
-            public void actionPerformed(ActionEvent e) {
-                LOG.fine("show proxy options");
-                OptionsDisplayer.getDefault().open("General"); // NOI18N
-            }
-        });
-    }
-    
-    private boolean showNoDownloadDialog(String cnb, String displayName) 
throws Exception {
-        DialogDescriptor networkProblem = new DialogDescriptor(
-                problemPanel(nodownload_header(displayName), 
nodownload_message(displayName)), // message
-                resolve_title(displayName), // title
-                true, // modal
-                null);
-        initButtons();
-        networkProblem.setOptions(new Object[] {tryAgain, 
NotifyDescriptor.CANCEL_OPTION});
-        networkProblem.setClosingOptions(new Object[] {tryAgain, 
NotifyDescriptor.CANCEL_OPTION});
-        networkProblem.setMessageType(NotifyDescriptor.WARNING_MESSAGE);
-        Dialog networkProblemDialog = 
DialogDisplayer.getDefault().createDialog(networkProblem);
-        networkProblemDialog.setVisible(true);
-        Object answer = networkProblem.getValue();
-        if (NotifyDescriptor.CANCEL_OPTION.equals(answer) || 
answer.equals(-1) /* escape */ ) {
-            LOG.fine("cancel no download dialog");
-            //throw new InterruptedException("user canceled download & 
install JUnit");
-            return false;
-        } else if (tryAgain.equals(answer)) {
-            LOG.fine("try again download()");
-            return download(cnb, displayName);
-        } else {
-            assert false : "Unknown " + answer;
-        }
-        assert false : "Unknown " + answer;
-        return false;
-    }
-    
-    private static JPanel searchingPanel(JLabel progressLabel, JComponent 
progressComponent) {
-        JPanel panel = new JPanel();
-        progressLabel.setLabelFor(progressComponent);
-        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(panel);
-        panel.setLayout(layout);
-        layout.setHorizontalGroup(
-            
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-            .addGroup(layout.createSequentialGroup()
-                .addContainerGap()
-                
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
-                    .addComponent(progressLabel, 
javax.swing.GroupLayout.Alignment.LEADING, 
javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, 
Short.MAX_VALUE)
-                    .addComponent(progressComponent, 
javax.swing.GroupLayout.Alignment.LEADING, 
javax.swing.GroupLayout.DEFAULT_SIZE, 399, Short.MAX_VALUE))
-                .addContainerGap())
-        );
-        layout.setVerticalGroup(
-            
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-            .addGroup(layout.createSequentialGroup()
-                .addGap(96, 96, 96)
-                .addComponent(progressLabel)
-                
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
-                .addComponent(progressComponent, 
javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, 
javax.swing.GroupLayout.PREFERRED_SIZE)
-                .addContainerGap(109, Short.MAX_VALUE))
-        );
-        return panel;
-    }
-    
-    private static JPanel problemPanel(String header, String message) {
-        JPanel panel = new JPanel();
-        JLabel jLabel1 = new javax.swing.JLabel();
-        JScrollPane jScrollPane1 = new javax.swing.JScrollPane();
-        JTextArea jTextArea1 = new javax.swing.JTextArea();
-
-        
jLabel1.setFont(jLabel1.getFont().deriveFont(jLabel1.getFont().getStyle() | 
java.awt.Font.BOLD));
-        jLabel1.setText(header);
-
-        jTextArea1.setColumns(20);
-        jTextArea1.setEditable(false);
-        jTextArea1.setLineWrap(true);
-        jTextArea1.setWrapStyleWord(true);
-        jTextArea1.setRows(5);
-        jTextArea1.setText(message);
-        jTextArea1.setOpaque(false);
-        jScrollPane1.setViewportView(jTextArea1);
-
-        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(panel);
-        panel.setLayout(layout);
-        layout.setHorizontalGroup(
-            
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-            .addGroup(layout.createSequentialGroup()
-                .addContainerGap()
-                
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-                    .addComponent(jScrollPane1, 
javax.swing.GroupLayout.DEFAULT_SIZE, 478, Short.MAX_VALUE)
-                    .addGroup(layout.createSequentialGroup()
-                        .addComponent(jLabel1)
-                        .addGap(107, 107, 107)))
-                .addContainerGap())
-        );
-        layout.setVerticalGroup(
-            
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-            .addGroup(layout.createSequentialGroup()
-                .addContainerGap()
-                .addComponent(jLabel1)
-                
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
-                .addComponent(jScrollPane1, 
javax.swing.GroupLayout.DEFAULT_SIZE, 133, Short.MAX_VALUE)
-                .addGap(82, 82, 82))
-        );
-        return panel;
-    }
-
-}
diff --git a/code.analysis/src/org/netbeans/modules/analysis/Utils.java 
b/code.analysis/src/org/netbeans/modules/analysis/Utils.java
--- a/code.analysis/src/org/netbeans/modules/analysis/Utils.java
+++ b/code.analysis/src/org/netbeans/modules/analysis/Utils.java
@@ -45,7 +45,7 @@
 import java.util.HashSet;
 import java.util.Set;
 import org.netbeans.modules.analysis.spi.Analyzer.MissingPlugin;
-import org.openide.util.Exceptions;
+import org.netbeans.modules.autoupdate.ui.api.PluginManager;
 
 /**
  *
@@ -57,11 +57,7 @@
         Set<MissingPlugin> plugins = new HashSet<MissingPlugin>(inPlugins);
 
         for (MissingPlugin missing : plugins) {
-            try {
-                new 
ModuleInstallerSupport().download(SPIAccessor.ACCESSOR.getCNB(missing), 
SPIAccessor.ACCESSOR.getDisplayName(missing));
-            } catch (Exception ex) {
-                Exceptions.printStackTrace(ex);
+            
PluginManager.installSingle(SPIAccessor.ACCESSOR.getCNB(missing), 
SPIAccessor.ACCESSOR.getDisplayName(missing));
             }
         }
     }
-}
diff --git a/findbugs.installer/manifest.mf b/findbugs.installer/manifest.mf
--- a/findbugs.installer/manifest.mf
+++ b/findbugs.installer/manifest.mf
@@ -4,5 +4,5 @@
 xOpenIDE-Module-Layer: org/netbeans/modules/findbugs/installer/layer.xml
 OpenIDE-Module-Localizing-Bundle: 
org/netbeans/modules/findbugs/installer/Bundle.properties
 OpenIDE-Module-Provides: org.netbeans.modules.findbugs.installer
-OpenIDE-Module-Specification-Version: 1.6
+OpenIDE-Module-Specification-Version: 1.7
 
diff --git a/findbugs.installer/nbproject/project.xml 
b/findbugs.installer/nbproject/project.xml
--- a/findbugs.installer/nbproject/project.xml
+++ b/findbugs.installer/nbproject/project.xml
@@ -15,19 +15,11 @@
                     </run-dependency>
                 </dependency>
                 <dependency>
-                    
<code-name-base>org.netbeans.modules.autoupdate.services</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>1.29</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
                     
<code-name-base>org.netbeans.modules.autoupdate.ui</code-name-base>
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>1.26</specification-version>
+                        <specification-version>1.35</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
diff --git 
a/findbugs.installer/src/org/netbeans/modules/findbugs/installer/FindBugsPanel.java
 
b/findbugs.installer/src/org/netbeans/modules/findbugs/installer/FindBugsPanel.java
--- 
a/findbugs.installer/src/org/netbeans/modules/findbugs/installer/FindBugsPanel.java
+++ 
b/findbugs.installer/src/org/netbeans/modules/findbugs/installer/FindBugsPanel.java
@@ -41,6 +41,7 @@
  */
 package org.netbeans.modules.findbugs.installer;
 
+import org.netbeans.modules.autoupdate.ui.api.PluginManager;
 import org.openide.util.Exceptions;
 import org.openide.util.NbBundle.Messages;
 
@@ -95,11 +96,7 @@
 
     @Messages("FindBugs_Library=FindBugs Library")
     private void installActionPerformed(java.awt.event.ActionEvent evt) 
{//GEN-FIRST:event_installActionPerformed
-        try {
-            new 
ModuleInstallerSupport().download("org.netbeans.modules.findbugs", 
Bundle.FindBugs_Library());
-        } catch (Exception ex) {
-            Exceptions.printStackTrace(ex);
-        }
+        PluginManager.installSingle("org.netbeans.modules.findbugs", 
Bundle.FindBugs_Library());
     }//GEN-LAST:event_installActionPerformed
 
     void load() {
diff --git 
a/findbugs.installer/src/org/netbeans/modules/findbugs/installer/ModuleInstallerSupport.java
 
b/findbugs.installer/src/org/netbeans/modules/findbugs/installer/ModuleInstallerSupport.java
deleted file mode 100644
--- 
a/findbugs.installer/src/org/netbeans/modules/findbugs/installer/ModuleInstallerSupport.java
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
- *
- * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
- * Other names may be trademarks of their respective owners.
- *
- * The contents of this file are subject to the terms of either the GNU
- * General Public License Version 2 only ("GPL") or the Common
- * Development and Distribution License("CDDL") (collectively, the
- * "License"). You may not use this file except in compliance with the
- * License. You can obtain a copy of the License at
- * http://www.netbeans.org/cddl-gplv2.html
- * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
- * specific language governing permissions and limitations under the
- * License.  When distributing the software, include this License Header
- * Notice in each file and include the License file at
- * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the GPL Version 2 section of the License file that
- * accompanied this code. If applicable, add the following below the
- * License Header, with the fields enclosed by brackets [] replaced by
- * your own identifying information:
- * "Portions Copyrighted [year] [name of copyright owner]"
- *
- * If you wish your version of this file to be governed by only the CDDL
- * or only the GPL Version 2, indicate your decision by adding
- * "[Contributor] elects to include this software in this distribution
- * under the [CDDL or GPL Version 2] license." If you do not indicate a
- * single choice of license, a recipient has the option to distribute
- * your version of this file under either the CDDL, the GPL Version 2 or
- * to extend the choice of license to its licensees as provided above.
- * However, if you add GPL Version 2 code and therefore, elected the GPL
- * Version 2 license, then the option applies only if the new code is
- * made subject to such option by the copyright holder.
- *
- * Contributor(s):
- *
- * Portions Copyrighted 2011 Sun Microsystems, Inc.
- */
-
-package org.netbeans.modules.findbugs.installer;
-
-import java.awt.event.ActionEvent;
-import org.netbeans.api.autoupdate.OperationSupport;
-import org.netbeans.api.autoupdate.OperationSupport.Restarter;
-import org.netbeans.api.options.OptionsDisplayer;
-import javax.swing.JButton;
-import javax.swing.JTextArea;
-import javax.swing.JPanel;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import java.awt.Dialog;
-import java.awt.event.ActionListener;
-import javax.swing.JComponent;
-import javax.swing.JLabel;
-import org.openide.DialogDisplayer;
-import java.io.IOException;
-import java.util.List;
-import javax.swing.JScrollPane;
-import org.netbeans.api.autoupdate.InstallSupport;
-import org.netbeans.api.autoupdate.OperationContainer;
-import org.netbeans.api.autoupdate.UpdateElement;
-import org.netbeans.api.autoupdate.UpdateManager;
-import org.netbeans.api.autoupdate.UpdateUnit;
-import org.netbeans.api.autoupdate.UpdateUnitProvider;
-import org.netbeans.api.autoupdate.UpdateUnitProviderFactory;
-import org.netbeans.api.progress.ProgressHandle;
-import org.netbeans.api.progress.ProgressHandleFactory;
-import org.netbeans.modules.autoupdate.ui.api.PluginManager;
-import org.openide.DialogDescriptor;
-import org.openide.NotifyDescriptor;
-import org.openide.awt.Mnemonics;
-import org.openide.util.NbBundle.Messages;
-import org.openide.util.RequestProcessor;
-import static org.netbeans.modules.findbugs.installer.Bundle.*;
-
-/**
- * Copied and adjusted from the JUnitLibraryDownloader
- */
-public class ModuleInstallerSupport  {
-    private static RequestProcessor RP = new 
RequestProcessor(ModuleInstallerSupport.class.getName(), 1);
-    private static final Logger LOG = 
Logger.getLogger(ModuleInstallerSupport.class.getName());
-
-    @Messages({
-        "searching_handle=Searching for \"{0}\" library on NetBeans plugin 
portal...",
-        "resolve_title=Resolve \"{0}\" Reference Problem",
-        "networkproblem_header=Unable to connect  to the NetBeans plugin 
portal",
-        "networkproblem_message=Check your proxy settings or try again 
later. "
-            + "The server may be unavailable at the moment. "
-            + "You may also want to make sure that your firewall is not 
blocking network traffic.",
-        "proxy_button=&Proxy Settings...",
-        "tryagain_button=Try &Again",
-        "nodownload_header=\"{0}\" module has not been downloaded",
-        "nodownload_message=You can try to download \"{0}\" module again",
-        "active_handle=Activating {0}"
-    })
-    
-    private JButton tryAgain;
-    private JButton proxySettings;
-
-    @SuppressWarnings("SleepWhileInLoop")
-    public boolean download(String cnb, final String displayName) throws 
Exception {
-        UpdateUnit unit = findModule(cnb);
-        if (unit == null) {
-            final ProgressHandle handle = 
ProgressHandleFactory.createHandle(searching_handle(displayName));
-            initButtons();
-            final DialogDescriptor searching = new 
DialogDescriptor(searchingPanel(new JLabel(searching_handle(displayName)),
-                    ProgressHandleFactory.createProgressComponent(handle)), 
resolve_title(displayName), true, null);
-            handle.setInitialDelay (0);
-            handle.start ();
-            searching.setOptions(new Object[] 
{NotifyDescriptor.CANCEL_OPTION});
-            searching.setMessageType(NotifyDescriptor.PLAIN_MESSAGE);
-            final Dialog dlg = 
DialogDisplayer.getDefault().createDialog(searching);
-            RP.post(new Runnable() {
-
-                @Override
-                public void run() {
-                    // May be first start, when no update lists have yet 
been downloaded.
-                    try {
-                        for (UpdateUnitProvider p : 
UpdateUnitProviderFactory.getDefault().getUpdateUnitProviders(true)) {
-                            p.refresh(handle, true);
-                        }
-                        // close searching
-                        dlg.dispose();
-                    } catch (IOException ex) {
-                        LOG.log(Level.FINE, ex.getMessage(), ex);
-                        if (! dlg.isVisible()) {
-                            LOG.fine("dialog not visible => do nothing");
-                            return ;
-                        }
-                        DialogDescriptor networkProblem = new 
DialogDescriptor(
-                                problemPanel(resolve_title(displayName), 
networkproblem_message()), // message
-                                networkproblem_header(), // title
-                                true, // modal
-                                null);
-                        networkProblem.setOptions(new Object[] {tryAgain, 
proxySettings, NotifyDescriptor.CANCEL_OPTION});
-                        networkProblem.setClosingOptions(new Object[] 
{tryAgain, NotifyDescriptor.CANCEL_OPTION});
-                        
networkProblem.setMessageType(NotifyDescriptor.WARNING_MESSAGE);
-                        Dialog networkProblemDialog = 
DialogDisplayer.getDefault().createDialog(networkProblem);
-                        networkProblemDialog.setVisible(true);
-                        Object answer = networkProblem.getValue();
-                        if (NotifyDescriptor.CANCEL_OPTION.equals(answer) || 
answer.equals(-1) /* escape */ ) {
-                            LOG.fine("cancel network problem dialog");
-                            searching.setValue(answer);
-                            dlg.dispose();
-                        } else if (tryAgain.equals(answer)) {
-                            LOG.fine("try again searching");
-                            RP.post(this);
-                        } else {
-                            assert false : "Unknown " + answer;
-                        }
-                    }
-                }
-            });
-            dlg.setVisible(true);
-            handle.finish();
-            if (NotifyDescriptor.CANCEL_OPTION.equals(searching.getValue()) 
|| searching.getValue().equals(-1) /* escape */) {
-                LOG.log(Level.FINE, "user canceled searching for {0}", cnb);
-                return showNoDownloadDialog(cnb, displayName);
-            }
-            unit = findModule(cnb);
-            if (unit == null) {
-                LOG.log(Level.FINE, "could not find {0} on any update site", 
cnb);
-                return showNoDownloadDialog(cnb, displayName);
-            }
-        }
-        // check if module installed
-        if (unit.getInstalled() != null) {
-            LOG.fine(unit.getInstalled() + " already installed. Is active? " 
+ unit.getInstalled().isEnabled());
-            if (unit.getInstalled().isEnabled()) {
-                throw new Exception(unit.getInstalled() + " already 
installed and active");
-            } else {
-                // activate it
-                OperationContainer<OperationSupport> oc = 
OperationContainer.createForEnable();
-                if (!oc.canBeAdded(unit, unit.getInstalled())) {
-                    throw new Exception("could not add " + 
unit.getInstalled() + " for activation");
-                }
-                for (UpdateElement req : 
oc.add(unit.getInstalled()).getRequiredElements()) {
-                    oc.add(req);
-                }
-                ProgressHandle activeHandle = 
ProgressHandleFactory.createHandle (active_handle(displayName));
-                Restarter restarter = 
oc.getSupport().doOperation(activeHandle);
-                assert restarter == null : "No Restater need to make " + 
unit.getInstalled() + " active";
-                // XXX new library & build.properties apparently do not show 
up immediately... how to listen properly?
-                return true;
-            }
-        }
-        List<UpdateElement> updates = unit.getAvailableUpdates();
-        if (updates.isEmpty()) {
-            throw new Exception("no updates for " + unit);
-        }
-        OperationContainer<InstallSupport> oc = 
OperationContainer.createForInstall();
-        UpdateElement element = updates.get(0);
-        if (!oc.canBeAdded(unit, element)) {
-            throw new Exception("could not add " + element + " to updates");
-        }
-        for (UpdateElement req : oc.add(element).getRequiredElements()) {
-            oc.add(req);
-        }
-        if (!PluginManager.openInstallWizard(oc)) {
-            LOG.fine("user canceled PM");
-            return showNoDownloadDialog(cnb, displayName);
-        }
-        return true;
-    }
-
-    private UpdateUnit findModule(String cnb) throws IOException {
-        for (UpdateUnit unit : 
UpdateManager.getDefault().getUpdateUnits(UpdateManager.TYPE.MODULE)) {
-            if (unit.getCodeName().equals(cnb)) {
-                return unit;
-            }
-        }
-        return null;
-    }
-    
-    private void initButtons() {
-        if (tryAgain != null) {
-            return ;
-        }
-        tryAgain = new JButton();
-        proxySettings = new JButton();
-        Mnemonics.setLocalizedText(tryAgain, tryagain_button());
-        Mnemonics.setLocalizedText(proxySettings, proxy_button());
-        proxySettings.addActionListener(new ActionListener() {
-            @Override
-            public void actionPerformed(ActionEvent e) {
-                LOG.fine("show proxy options");
-                OptionsDisplayer.getDefault().open("General"); // NOI18N
-            }
-        });
-    }
-    
-    private boolean showNoDownloadDialog(String cnb, String displayName) 
throws Exception {
-        DialogDescriptor networkProblem = new DialogDescriptor(
-                problemPanel(nodownload_header(displayName), 
nodownload_message(displayName)), // message
-                resolve_title(displayName), // title
-                true, // modal
-                null);
-        initButtons();
-        networkProblem.setOptions(new Object[] {tryAgain, 
NotifyDescriptor.CANCEL_OPTION});
-        networkProblem.setClosingOptions(new Object[] {tryAgain, 
NotifyDescriptor.CANCEL_OPTION});
-        networkProblem.setMessageType(NotifyDescriptor.WARNING_MESSAGE);
-        Dialog networkProblemDialog = 
DialogDisplayer.getDefault().createDialog(networkProblem);
-        networkProblemDialog.setVisible(true);
-        Object answer = networkProblem.getValue();
-        if (NotifyDescriptor.CANCEL_OPTION.equals(answer) || 
answer.equals(-1) /* escape */ ) {
-            LOG.fine("cancel no download dialog");
-            //throw new InterruptedException("user canceled download & 
install JUnit");
-            return false;
-        } else if (tryAgain.equals(answer)) {
-            LOG.fine("try again download()");
-            return download(cnb, displayName);
-        } else {
-            assert false : "Unknown " + answer;
-        }
-        assert false : "Unknown " + answer;
-        return false;
-    }
-    
-    private static JPanel searchingPanel(JLabel progressLabel, JComponent 
progressComponent) {
-        JPanel panel = new JPanel();
-        progressLabel.setLabelFor(progressComponent);
-        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(panel);
-        panel.setLayout(layout);
-        layout.setHorizontalGroup(
-            
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-            .addGroup(layout.createSequentialGroup()
-                .addContainerGap()
-                
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
-                    .addComponent(progressLabel, 
javax.swing.GroupLayout.Alignment.LEADING, 
javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, 
Short.MAX_VALUE)
-                    .addComponent(progressComponent, 
javax.swing.GroupLayout.Alignment.LEADING, 
javax.swing.GroupLayout.DEFAULT_SIZE, 399, Short.MAX_VALUE))
-                .addContainerGap())
-        );
-        layout.setVerticalGroup(
-            
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-            .addGroup(layout.createSequentialGroup()
-                .addGap(96, 96, 96)
-                .addComponent(progressLabel)
-                
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
-                .addComponent(progressComponent, 
javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, 
javax.swing.GroupLayout.PREFERRED_SIZE)
-                .addContainerGap(109, Short.MAX_VALUE))
-        );
-        return panel;
-    }
-    
-    private static JPanel problemPanel(String header, String message) {
-        JPanel panel = new JPanel();
-        JLabel jLabel1 = new javax.swing.JLabel();
-        JScrollPane jScrollPane1 = new javax.swing.JScrollPane();
-        JTextArea jTextArea1 = new javax.swing.JTextArea();
-
-        
jLabel1.setFont(jLabel1.getFont().deriveFont(jLabel1.getFont().getStyle() | 
java.awt.Font.BOLD));
-        jLabel1.setText(header);
-
-        jTextArea1.setColumns(20);
-        jTextArea1.setEditable(false);
-        jTextArea1.setLineWrap(true);
-        jTextArea1.setWrapStyleWord(true);
-        jTextArea1.setRows(5);
-        jTextArea1.setText(message);
-        jTextArea1.setOpaque(false);
-        jScrollPane1.setViewportView(jTextArea1);
-
-        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(panel);
-        panel.setLayout(layout);
-        layout.setHorizontalGroup(
-            
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-            .addGroup(layout.createSequentialGroup()
-                .addContainerGap()
-                
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-                    .addComponent(jScrollPane1, 
javax.swing.GroupLayout.DEFAULT_SIZE, 478, Short.MAX_VALUE)
-                    .addGroup(layout.createSequentialGroup()
-                        .addComponent(jLabel1)
-                        .addGap(107, 107, 107)))
-                .addContainerGap())
-        );
-        layout.setVerticalGroup(
-            
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-            .addGroup(layout.createSequentialGroup()
-                .addContainerGap()
-                .addComponent(jLabel1)
-                
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
-                .addComponent(jScrollPane1, 
javax.swing.GroupLayout.DEFAULT_SIZE, 133, Short.MAX_VALUE)
-                .addGap(82, 82, 82))
-        );
-        return panel;
-    }
-
-}
diff --git a/junit/manifest.mf b/junit/manifest.mf
--- a/junit/manifest.mf
+++ b/junit/manifest.mf
@@ -2,6 +2,6 @@
 OpenIDE-Module: org.netbeans.modules.junit/2
 OpenIDE-Module-Localizing-Bundle: 
org/netbeans/modules/junit/Bundle.properties
 OpenIDE-Module-Layer: org/netbeans/modules/junit/resources/layer.xml
-OpenIDE-Module-Specification-Version: 2.55
+OpenIDE-Module-Specification-Version: 2.56
 OpenIDE-Module-Needs: javax.script.ScriptEngine.freemarker
 AutoUpdate-Show-In-Client: false
diff --git a/junit/nbproject/project.xml b/junit/nbproject/project.xml
--- a/junit/nbproject/project.xml
+++ b/junit/nbproject/project.xml
@@ -101,19 +101,11 @@
                     </run-dependency>
                 </dependency>
                 <dependency>
-                    
<code-name-base>org.netbeans.modules.autoupdate.services</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>1.23</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
                     
<code-name-base>org.netbeans.modules.autoupdate.ui</code-name-base>
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>1.20</specification-version>
+                        <specification-version>1.35</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
diff --git a/junit/src/org/netbeans/modules/junit/JUnitLibraryDownloader.java 
b/junit/src/org/netbeans/modules/junit/JUnitLibraryDefiner.java
rename from junit/src/org/netbeans/modules/junit/JUnitLibraryDownloader.java
rename to junit/src/org/netbeans/modules/junit/JUnitLibraryDefiner.java
--- a/junit/src/org/netbeans/modules/junit/JUnitLibraryDownloader.java
+++ b/junit/src/org/netbeans/modules/junit/JUnitLibraryDefiner.java
@@ -42,42 +42,15 @@
 
 package org.netbeans.modules.junit;
 
-import java.awt.event.ActionEvent;
-import org.netbeans.api.autoupdate.OperationSupport;
-import org.netbeans.api.autoupdate.OperationSupport.Restarter;
-import org.netbeans.api.options.OptionsDisplayer;
 import javax.swing.JButton;
-import javax.swing.JTextArea;
-import javax.swing.JPanel;
-import java.util.logging.Level;
 import java.util.logging.Logger;
-import java.awt.Dialog;
-import java.awt.event.ActionListener;
-import javax.swing.JComponent;
-import javax.swing.JLabel;
-import org.openide.DialogDisplayer;
-import java.io.IOException;
-import java.util.List;
 import java.util.concurrent.Callable;
-import javax.swing.JScrollPane;
-import org.netbeans.api.autoupdate.InstallSupport;
-import org.netbeans.api.autoupdate.OperationContainer;
-import org.netbeans.api.autoupdate.UpdateElement;
-import org.netbeans.api.autoupdate.UpdateManager;
-import org.netbeans.api.autoupdate.UpdateUnit;
-import org.netbeans.api.autoupdate.UpdateUnitProvider;
-import org.netbeans.api.autoupdate.UpdateUnitProviderFactory;
-import org.netbeans.api.progress.ProgressHandle;
-import org.netbeans.api.progress.ProgressHandleFactory;
 import org.netbeans.api.project.libraries.Library;
 import org.netbeans.api.project.libraries.LibraryManager;
 import org.netbeans.modules.autoupdate.ui.api.PluginManager;
 import 
org.netbeans.spi.java.project.support.ui.BrokenReferencesSupport.LibraryDefiner;
-import org.openide.DialogDescriptor;
-import org.openide.NotifyDescriptor;
 import org.openide.awt.Mnemonics;
 import org.openide.util.NbBundle.Messages;
-import org.openide.util.RequestProcessor;
 import org.openide.util.lookup.ServiceProvider;
 import static org.netbeans.modules.junit.Bundle.*;
 
@@ -85,27 +58,11 @@
  * Defines JUnit 3.x/4.x libraries by downloading their defining modules.
  */
 @ServiceProvider(service=LibraryDefiner.class)
-public class JUnitLibraryDownloader implements LibraryDefiner {
-    private static RequestProcessor RP = new 
RequestProcessor(JUnitLibraryDownloader.class.getName(), 1);
-    private static final Logger LOG = 
Logger.getLogger(JUnitLibraryDownloader.class.getName());
+public class JUnitLibraryDefiner implements LibraryDefiner {
 
     @Messages({
-        "searching_handle=Searching for \"junit\" library on NetBeans plugin 
portal...",
-        "resolve_title=Resolve \"junit\" Reference Problem",
-        "networkproblem_header=Unable to connect  to the NetBeans plugin 
portal",
-        "networkproblem_message=Check your proxy settings or try again 
later. "
-            + "The server may be unavailable at the moment. "
-            + "You may also want to make sure that your firewall is not 
blocking network traffic. \n\n"
-            + "If you have the missing \"junit\" library, you can resolve 
the reference "
-            + "problem manually using Library Manager.",
-        "proxy_button=&Proxy Settings...",
         "library_button=&Library Manager...",
-        "tryagain_button=Try &Again",
-        "nodownload_header=\"junit\" library has not been downloaded",
-        "nodownload_message=You can try to download \"junit\" library again, 
or \n\n"
-            + "if you have the missing \"junit\" library, you can resolve 
the reference "
-            + "problem manually using Library Manager.",
-        "active_handle=Activating JUnit"
+        "library_name=junit"
     })
     
     public @Override Callable<Library> missingLibrary(final String name) {
@@ -113,133 +70,14 @@
             return null;
         }
         return new Callable<Library>() {
-            public @Override Library call() throws Exception {
-                return download(name);
-            }
-        };
-    }
-    
-    private JButton libraryManager;
-    private JButton tryAgain;
-    private JButton proxySettings;
 
     @SuppressWarnings("SleepWhileInLoop")
-    private Library download(String name) throws Exception {
-        UpdateUnit unit = findJUnitLib();
-        if (unit == null) {
-            final ProgressHandle handle = 
ProgressHandleFactory.createHandle(searching_handle());
-            initButtons();
-            final DialogDescriptor searching = new 
DialogDescriptor(searchingPanel(new JLabel(searching_handle()),
-                    ProgressHandleFactory.createProgressComponent(handle)), 
resolve_title(), true, null);
-            handle.setInitialDelay (0);
-            handle.start ();
-            searching.setOptions(new Object[] 
{NotifyDescriptor.CANCEL_OPTION});
-            searching.setMessageType(NotifyDescriptor.PLAIN_MESSAGE);
-            final Dialog dlg = 
DialogDisplayer.getDefault().createDialog(searching);
-            RP.post(new Runnable() {
-
-                @Override
-                public void run() {
-                    // May be first start, when no update lists have yet 
been downloaded.
-                    try {
-                        for (UpdateUnitProvider p : 
UpdateUnitProviderFactory.getDefault().getUpdateUnitProviders(true)) {
-                            p.refresh(handle, true);
-                        }
-                        // close searching
-                        dlg.dispose();
-                    } catch (IOException ex) {
-                        
Logger.getLogger(JUnitLibraryDownloader.class.getName()).log(Level.FINE, 
ex.getMessage(), ex);
-                        if (! dlg.isVisible()) {
-                            LOG.fine("dialog not visible => do nothing");
-                            return ;
-                        }
-                        DialogDescriptor networkProblem = new 
DialogDescriptor(
-                                problemPanel(resolve_title(), 
networkproblem_message()), // message
-                                networkproblem_header(), // title
-                                true, // modal
-                                null);
-                        networkProblem.setOptions(new Object[] {tryAgain, 
proxySettings, NotifyDescriptor.CANCEL_OPTION});
-                        networkProblem.setAdditionalOptions(new Object[] 
{libraryManager});
-                        networkProblem.setClosingOptions(new Object[] 
{libraryManager, tryAgain, NotifyDescriptor.CANCEL_OPTION});
-                        
networkProblem.setMessageType(NotifyDescriptor.WARNING_MESSAGE);
-                        Dialog networkProblemDialog = 
DialogDisplayer.getDefault().createDialog(networkProblem);
-                        networkProblemDialog.setVisible(true);
-                        Object answer = networkProblem.getValue();
-                        if (NotifyDescriptor.CANCEL_OPTION.equals(answer) || 
answer.equals(-1) /* escape */ ) {
-                            LOG.fine("cancel network problem dialog");
-                            searching.setValue(answer);
-                            dlg.dispose();
-                        } else if (tryAgain.equals(answer)) {
-                            LOG.fine("try again searching");
-                            RP.post(this);
-                        } else if (libraryManager.equals(answer)) {
-                            LOG.fine("open library manager");
-                            searching.setValue(answer);
-                            dlg.dispose();
-                        } else {
-                            assert false : "Unknown " + answer;
-                        }
-                    }
-                }
-            });
-            dlg.setVisible(true);
-            handle.finish();
-            if (NotifyDescriptor.CANCEL_OPTION.equals(searching.getValue()) 
|| searching.getValue().equals(-1) /* escape */) {
-                LOG.fine("user canceled searching JUnit");
-                return showNoDownloadDialog(name);
-            } else if (libraryManager.equals(searching.getValue())) {
-                throw new Exception("user canceled searching");
-            }
-            unit = findJUnitLib();
-            if (unit == null) {
-                LOG.fine("could not find junitlib on any update site");
-                return showNoDownloadDialog(name);
-            }
-        }
-        // check if JUnit installed
-        if (unit.getInstalled() != null) {
-            LOG.fine(unit.getInstalled() + " already installed. Is active? " 
+ unit.getInstalled().isEnabled());
-            if (unit.getInstalled().isEnabled()) {
-                throw new Exception(unit.getInstalled() + " already 
installed and active");
-            } else {
-                // activate it
-                OperationContainer<OperationSupport> oc = 
OperationContainer.createForEnable();
-                if (!oc.canBeAdded(unit, unit.getInstalled())) {
-                    throw new Exception("could not add " + 
unit.getInstalled() + " for activation");
-                }
-                for (UpdateElement req : 
oc.add(unit.getInstalled()).getRequiredElements()) {
-                    oc.add(req);
-                }
-                ProgressHandle activeHandle = 
ProgressHandleFactory.createHandle (active_handle());
-                Restarter restarter = 
oc.getSupport().doOperation(activeHandle);
-                assert restarter == null : "No Restater need to make " + 
unit.getInstalled() + " active";
-                // XXX new library & build.properties apparently do not show 
up immediately... how to listen properly?
-                for (int i = 0; i < 10; i++) {
-                    Library lib = 
LibraryManager.getDefault().getLibrary(name);
-                    if (lib != null) {
-                        return lib;
-                    }
-                    Thread.sleep(1000);
-                }
-                LOG.info("junitlib failed to make active properly");
-                return showNoDownloadDialog(name);
-            }
-        }
-        List<UpdateElement> updates = unit.getAvailableUpdates();
-        if (updates.isEmpty()) {
-            throw new Exception("no updates for " + unit);
-        }
-        OperationContainer<InstallSupport> oc = 
OperationContainer.createForInstall();
-        UpdateElement element = updates.get(0);
-        if (!oc.canBeAdded(unit, element)) {
-            throw new Exception("could not add " + element + " to updates");
-        }
-        for (UpdateElement req : oc.add(element).getRequiredElements()) {
-            oc.add(req);
-        }
-        if (!PluginManager.openInstallWizard(oc)) {
-            LOG.fine("user canceled PM");
-            return showNoDownloadDialog(name);
+            public @Override Library call() throws Exception {
+                JButton libraryManager = new JButton();
+                Mnemonics.setLocalizedText(libraryManager, library_button());
+                Object ret = 
PluginManager.installSingle("org.netbeans.modules.junitlib", library_name(), 
libraryManager);
+                if (libraryManager.equals(ret)) {
+                    throw new Exception("junitlib failed/canceled to install 
properly, open library manager instaed");
         }
         // XXX new library & build.properties apparently do not show up 
immediately... how to listen properly?
         for (int i = 0; i < 20; i++) {
@@ -249,136 +87,9 @@
             }
             Thread.sleep(1000);
         }
-        LOG.info("junitlib failed to install properly");
-        return showNoDownloadDialog(name);
-    }
-
-    private UpdateUnit findJUnitLib() throws IOException {
-        for (UpdateUnit unit : 
UpdateManager.getDefault().getUpdateUnits(UpdateManager.TYPE.MODULE)) {
-            if (unit.getCodeName().equals("org.netbeans.modules.junitlib")) {
-                return unit;
-            }
-        }
         return null;
     }
-    
-    private void initButtons() {
-        if (libraryManager != null) {
-            return ;
-        }
-        libraryManager = new JButton();
-        tryAgain = new JButton();
-        proxySettings = new JButton();
-        Mnemonics.setLocalizedText(tryAgain, tryagain_button());
-        Mnemonics.setLocalizedText(libraryManager, library_button());
-        Mnemonics.setLocalizedText(proxySettings, proxy_button());
-        proxySettings.addActionListener(new ActionListener() {
-            @Override
-            public void actionPerformed(ActionEvent e) {
-                LOG.fine("show proxy options");
-                OptionsDisplayer.getDefault().open("General"); // NOI18N
-            }
-        });
-    }
-    
-    private Library showNoDownloadDialog(String name) throws Exception {
-        DialogDescriptor networkProblem = new DialogDescriptor(
-                problemPanel(nodownload_header(), nodownload_message()), // 
message
-                resolve_title(), // title
-                true, // modal
-                null);
-        initButtons();
-        networkProblem.setOptions(new Object[] {tryAgain, 
NotifyDescriptor.CANCEL_OPTION});
-        networkProblem.setAdditionalOptions(new Object[] {libraryManager});
-        networkProblem.setClosingOptions(new Object[] {libraryManager, 
tryAgain, NotifyDescriptor.CANCEL_OPTION});
-        networkProblem.setMessageType(NotifyDescriptor.WARNING_MESSAGE);
-        Dialog networkProblemDialog = 
DialogDisplayer.getDefault().createDialog(networkProblem);
-        networkProblemDialog.setVisible(true);
-        Object answer = networkProblem.getValue();
-        if (NotifyDescriptor.CANCEL_OPTION.equals(answer) || 
answer.equals(-1) /* escape */ ) {
-            LOG.fine("cancel no download dialog");
-            //throw new InterruptedException("user canceled download & 
install JUnit");
-            return null;
-        } else if (tryAgain.equals(answer)) {
-            LOG.fine("try again download()");
-            return download(name);
-        } else if (libraryManager.equals(answer)) {
-            LOG.fine("open library manager");
-            throw new Exception("junitlib failed/canceled to install 
properly, open library manager instaed");            
-        } else {
-            assert false : "Unknown " + answer;
-        }
-        assert false : "Unknown " + answer;
-        return null;
-    }
-    
-    private static JPanel searchingPanel(JLabel progressLabel, JComponent 
progressComponent) {
-        JPanel panel = new JPanel();
-        progressLabel.setLabelFor(progressComponent);
-        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(panel);
-        panel.setLayout(layout);
-        layout.setHorizontalGroup(
-            
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-            .addGroup(layout.createSequentialGroup()
-                .addContainerGap()
-                
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
-                    .addComponent(progressLabel, 
javax.swing.GroupLayout.Alignment.LEADING, 
javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, 
Short.MAX_VALUE)
-                    .addComponent(progressComponent, 
javax.swing.GroupLayout.Alignment.LEADING, 
javax.swing.GroupLayout.DEFAULT_SIZE, 399, Short.MAX_VALUE))
-                .addContainerGap())
-        );
-        layout.setVerticalGroup(
-            
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-            .addGroup(layout.createSequentialGroup()
-                .addGap(96, 96, 96)
-                .addComponent(progressLabel)
-                
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
-                .addComponent(progressComponent, 
javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, 
javax.swing.GroupLayout.PREFERRED_SIZE)
-                .addContainerGap(109, Short.MAX_VALUE))
-        );
-        return panel;
-    }
-    
-    private static JPanel problemPanel(String header, String message) {
-        JPanel panel = new JPanel();
-        JLabel jLabel1 = new javax.swing.JLabel();
-        JScrollPane jScrollPane1 = new javax.swing.JScrollPane();
-        JTextArea jTextArea1 = new javax.swing.JTextArea();
-
-        
jLabel1.setFont(jLabel1.getFont().deriveFont(jLabel1.getFont().getStyle() | 
java.awt.Font.BOLD));
-        jLabel1.setText(header);
-
-        jTextArea1.setColumns(20);
-        jTextArea1.setEditable(false);
-        jTextArea1.setLineWrap(true);
-        jTextArea1.setWrapStyleWord(true);
-        jTextArea1.setRows(5);
-        jTextArea1.setText(message);
-        jTextArea1.setOpaque(false);
-        jScrollPane1.setViewportView(jTextArea1);
-
-        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(panel);
-        panel.setLayout(layout);
-        layout.setHorizontalGroup(
-            
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-            .addGroup(layout.createSequentialGroup()
-                .addContainerGap()
-                
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-                    .addComponent(jScrollPane1, 
javax.swing.GroupLayout.DEFAULT_SIZE, 478, Short.MAX_VALUE)
-                    .addGroup(layout.createSequentialGroup()
-                        .addComponent(jLabel1)
-                        .addGap(107, 107, 107)))
-                .addContainerGap())
-        );
-        layout.setVerticalGroup(
-            
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-            .addGroup(layout.createSequentialGroup()
-                .addContainerGap()
-                .addComponent(jLabel1)
-                
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
-                .addComponent(jScrollPane1, 
javax.swing.GroupLayout.DEFAULT_SIZE, 133, Short.MAX_VALUE)
-                .addGap(82, 82, 82))
-        );
-        return panel;
+        };
     }
 
 }

[hg] main-silver: #196538 - Extend UI API for PM.openInstallWiza...

Petr Hejl 02/13/2013

Project Features

About this Project

Editor was started in November 2009, is owned by Martin Ryzl, and has 147 members.
By use of this website, you agree to the NetBeans Policies and Terms of Use (revision 20140418.2d69abc). © 2013, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo
 
 
Close
loading
Please Confirm
Close