/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.netbeans.modules.project.ui;

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.text.Collator;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.swing.DefaultListModel;
import javax.swing.Icon;
import javax.swing.JFileChooser;
import javax.swing.ListModel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileView;
import org.netbeans.api.project.Project;
import org.netbeans.api.project.ProjectManager;
import org.netbeans.api.project.ProjectUtils;
import org.netbeans.api.queries.CollocationQuery;
import org.netbeans.spi.project.ProjectContainerProvider;
import org.netbeans.spi.project.SubprojectProvider;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.util.Cancellable;
import org.openide.util.Exceptions;
import org.openide.util.NbBundle;
import org.openide.util.RequestProcessor;
import org.openide.util.Utilities;

/**
 * Special component on side of project filechooser.
 */
public class ProjectChooserAccessory extends javax.swing.JPanel
    implements ActionListener, PropertyChangeListener {

    private RequestProcessor.Task updateSubprojectsTask;
    private RequestProcessor.Task displayNameTask;
    private RequestProcessor RP;
    private RequestProcessor RP2;
    
    ModelUpdater modelUpdater;  //#101227 -> non-private

    private Map<Project,Set<? extends Project>> subprojectsCache = new HashMap<Project,Set<? extends Project>>(); // #59098
    /** Creates new form ProjectChooserAccessory */
    public ProjectChooserAccessory(JFileChooser chooser, boolean isOpenSubprojects) {
        initComponents();

        modelUpdater = new ModelUpdater();
        //#98080
        RP = new RequestProcessor(ModelUpdater.class.getName(), 1);
        RP2 = new RequestProcessor(ModelUpdater.class.getName(), 1);
        updateSubprojectsTask = RP.create(modelUpdater);
        updateSubprojectsTask.setPriority( Thread.MIN_PRIORITY );

        // Listen on the subproject checkbox to change the option accordingly
        jCheckBoxSubprojects.setSelected( isOpenSubprojects );
        jCheckBoxSubprojects.addActionListener( this );

        // Listen on the chooser to update the Accessory
        chooser.addPropertyChangeListener( this );

        // Set default list model for the subprojects list
        jListSubprojects.setModel( new DefaultListModel() );

        // Disable the Accessory. JFileChooser does not select a file
        // by default
        setAccessoryEnablement( false, 0 );
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        jLabelProjectName = new javax.swing.JLabel();
        jTextFieldProjectName = new javax.swing.JTextField();
        jCheckBoxSubprojects = new javax.swing.JCheckBox();
        jScrollPaneSubprojects = new javax.swing.JScrollPane();
        jListSubprojects = new javax.swing.JList();

        setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 12, 0, 0));
        setLayout(new java.awt.GridBagLayout());

        jLabelProjectName.setLabelFor(jTextFieldProjectName);
        org.openide.awt.Mnemonics.setLocalizedText(jLabelProjectName, org.openide.util.NbBundle.getMessage(ProjectChooserAccessory.class, "LBL_PrjChooser_ProjectName_Label")); // NOI18N
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 2, 0);
        add(jLabelProjectName, gridBagConstraints);
        jLabelProjectName.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(ProjectChooserAccessory.class, "AN_ProjectName")); // NOI18N
        jLabelProjectName.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(ProjectChooserAccessory.class, "AD_ProjectName")); // NOI18N

        jTextFieldProjectName.setEditable(false);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 6, 0);
        add(jTextFieldProjectName, gridBagConstraints);

        org.openide.awt.Mnemonics.setLocalizedText(jCheckBoxSubprojects, org.openide.util.NbBundle.getMessage(ProjectChooserAccessory.class, "LBL_PrjChooser_Subprojects_CheckBox")); // NOI18N
        jCheckBoxSubprojects.setMargin(new java.awt.Insets(2, 0, 2, 2));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 2, 0);
        add(jCheckBoxSubprojects, gridBagConstraints);
        jCheckBoxSubprojects.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(ProjectChooserAccessory.class, "ACSD_ProjectChooserAccessory_jCheckBoxSubprojects")); // NOI18N

        jListSubprojects.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        jListSubprojects.setEnabled(false);
        jScrollPaneSubprojects.setViewportView(jListSubprojects);
        jListSubprojects.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(ProjectChooserAccessory.class, "ACSN_ProjectChooserAccessory_jListSubprojects")); // NOI18N
        jListSubprojects.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(ProjectChooserAccessory.class, "ACSD_ProjectChooserAccessory_jListSubprojects")); // NOI18N

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
        gridBagConstraints.gridheight = java.awt.GridBagConstraints.REMAINDER;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        add(jScrollPaneSubprojects, gridBagConstraints);
    }// </editor-fold>//GEN-END:initComponents


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JCheckBox jCheckBoxSubprojects;
    private javax.swing.JLabel jLabelProjectName;
    private javax.swing.JList jListSubprojects;
    private javax.swing.JScrollPane jScrollPaneSubprojects;
    private javax.swing.JTextField jTextFieldProjectName;
    // End of variables declaration//GEN-END:variables

    // Implementation of action listener ---------------------------------------

    @Override
    public void actionPerformed( ActionEvent e ) {
        if ( e.getSource() == jCheckBoxSubprojects ) {
            OpenProjectListSettings.getInstance().setOpenSubprojects( jCheckBoxSubprojects.isSelected() );
        }
    }

    @Override
    public void propertyChange( PropertyChangeEvent e ) {
        if ( JFileChooser.SELECTED_FILE_CHANGED_PROPERTY.equals( e.getPropertyName() ) ||
             JFileChooser.SELECTED_FILES_CHANGED_PROPERTY.equals( e.getPropertyName() ) ) {

            // We have to update the Accessory
            JFileChooser chooser = (JFileChooser)e.getSource();
            final ListModel spListModel = jListSubprojects.getModel();


            final File[] projectDirs;
            if ( chooser.isMultiSelectionEnabled() ) {
                projectDirs = chooser.getSelectedFiles();
            }
            else {
                projectDirs = new File[] { chooser.getSelectedFile() };
            }

            // #87119: do not block EQ loading projects
            jTextFieldProjectName.setText(NbBundle.getMessage(ProjectChooserAccessory.class, "MSG_PrjChooser_WaitMessage"));

            if (displayNameTask != null) {
                displayNameTask.cancel();
            }

            displayNameTask = RP2.post(new Runnable() {
                @Override
                public void run() {

            final List<Project> projects = new ArrayList<Project>( projectDirs.length );
            //#155766 load the display names off the AWT thead.
            final List<String> projectNames = new ArrayList<String>(projectDirs.length);
            for (File dir : projectDirs) {
                if (dir != null) {
                    if (Thread.interrupted()) {
                        return;
                    }
                    Project project = getProject(FileUtil.normalizeFile(dir));
                    if ( project != null ) {
                        projects.add( project );
                        projectNames.add(ProjectUtils.getInformation(project).getDisplayName());
                    }
                }
            }
            if (Thread.interrupted()) {
                return;
            }
            EventQueue.invokeLater(new Runnable() {
                        @Override
                public void run() {

            if ( !projects.isEmpty() ) {
                // Enable all components acessory
                setAccessoryEnablement( true, projects.size() );

                if ( projects.size() == 1 ) {
                    String projectName = projectNames.get(0);
                    jTextFieldProjectName.setText( projectName );
                    jTextFieldProjectName.setToolTipText( projectName );
                }
                else {
                    jTextFieldProjectName.setText(NbBundle.getMessage(ProjectChooserAccessory.class, "LBL_PrjChooser_Multiselection", projects.size()));

                    StringBuffer toolTipText = new StringBuffer( "<html>" ); // NOI18N
                    for(String str : projectNames) {
                        toolTipText.append( str );
                        toolTipText.append( "<br>" ); // NOI18N
                    }
                    toolTipText.setLength(toolTipText.length() - "<br>".length());
                    toolTipText.append( "</html>" ); // NOI18N
                    jTextFieldProjectName.setToolTipText( toolTipText.toString() );
                }

                if (spListModel instanceof DefaultListModel) {
                    ((DefaultListModel)spListModel).clear();
                } else {
                    jListSubprojects.setListData (new String[0]);
                }

                if (modelUpdater != null) { // #72495
                    modelUpdater.projects = projects;
                    updateSubprojectsTask.schedule( 100 );
                }
            }
            else {
                // Clear the accessory data if the dir is not project dir
                jTextFieldProjectName.setText( "" ); // NOI18N
                if (modelUpdater != null) { // #72495
                    modelUpdater.projects = null;
                }

                if (spListModel instanceof DefaultListModel) {
                    ((DefaultListModel)spListModel).clear();
                } else {
                    jListSubprojects.setListData (new String[0]);
                }

                // Disable all components in accessory
                setAccessoryEnablement( false, 0 );

                // But, in case it is a load error, show that:
                if (projectDirs.length == 1 && projectDirs[0] != null) {
                    File dir = FileUtil.normalizeFile(projectDirs[0]);
                    FileObject fo = FileUtil.toFileObject(dir);
                    ProjectManager.getDefault().clearNonProjectCache(); // #113976: otherwise isProject will be false
                    if (fo != null && fo.isFolder() && ProjectManager.getDefault().isProject(fo)) {
                        try {
                            Project prj = ProjectManager.getDefault().findProject(fo);
                            if (prj == null) {
                                jTextFieldProjectName.setText(NbBundle.getMessage(ProjectChooserAccessory.class, "LBL_PrjChooser_Unrecognized"));
                                // Only so it can be focussed and message scrolled accessibly:
                                jLabelProjectName.setEnabled(true);
                                jTextFieldProjectName.setEnabled(true);
                            }
                        } catch (IOException x) {
                            String msg = Exceptions.findLocalizedMessage(x);
                            if (msg == null) {
                                msg = x.getLocalizedMessage();
                            }
                            jTextFieldProjectName.setText(msg);
                            jTextFieldProjectName.setCaretPosition(0);
                            Color error = UIManager.getColor("nb.errorForeground"); // NOI18N
                            if (error != null) {
                                jTextFieldProjectName.setForeground(error);
                            }
                            // Only so it can be focussed and message scrolled accessibly:
                            jLabelProjectName.setEnabled(true);
                            jTextFieldProjectName.setEnabled(true);
                        }
                    }
                }
            }

                        }
                    });
                }
            }, 100, Thread.MIN_PRIORITY);
        }
        else if ( JFileChooser.DIRECTORY_CHANGED_PROPERTY.equals( e.getPropertyName() ) ) {
            // Selection lost => disable accessory
            setAccessoryEnablement( false, 0 );
        }
    }


    // Private methods ---------------------------------------------------------

    private static Project getProject( File dir ) {
        return OpenProjectList.fileToProject( dir );
    }

    private static ProjectManager.Result getProjectResult(File dir) {
        FileObject fo = FileUtil.toFileObject(dir);
        if (fo != null && /* #60518 */ fo.isFolder()) {
            return ProjectManager.getDefault().isProject2(fo);
        } else {
            return null;
        }

    }

    private void setAccessoryEnablement( boolean enable, int numberOfProjects ) {
        jLabelProjectName.setEnabled( enable );
        jTextFieldProjectName.setEnabled( enable );
        jTextFieldProjectName.setForeground(/* i.e. L&F default */null);
        jCheckBoxSubprojects.setEnabled( enable );
        jScrollPaneSubprojects.setEnabled( enable );
    }


    /**
     * Get a slash-separated relative path from f1 to f2, if they are collocated
     * and this is possible.
     * May return null.
     */
    private static String relativizePath(File f1, File f2) {
        if (f1 == null || f2 == null) {
            return null;
        }
        if (!CollocationQuery.areCollocated(f1, f2)) {
            return null;
        }
        // Copied from PropertyUtils.relativizeFile, more or less:
        StringBuffer b = new StringBuffer();
        File base = f1;
        String filepath = f2.getAbsolutePath();
        while (!filepath.startsWith(slashify(base.getAbsolutePath()))) {
            base = base.getParentFile();
            if (base == null) {
                return null;
            }
            if (base.equals(f2)) {
                // #61687: file is a parent of basedir
                b.append(".."); // NOI18N
                return b.toString();
            }
            b.append("../"); // NOI18N
        }
        URI u = Utilities.toURI(base).relativize(Utilities.toURI(f2));
        assert !u.isAbsolute() : u + " from " + f1 + " and " + f2 + " with common root " + base;
        b.append(u.getPath());
        if (b.charAt(b.length() - 1) == '/') {
            // file is an existing directory and file.toURI ends in /
            // we do not want the trailing slash
            b.setLength(b.length() - 1);
        }
        return b.toString();
    }
    private static String slashify(String path) {
        if (path.endsWith(File.separator)) {
            return path;
        } else {
            return path + File.separatorChar;
        }
    }


    // Other methods -----------------------------------------------------------

    /** Factory method for project chooser
     */
    public static JFileChooser createProjectChooser( boolean defaultAccessory ) {

        ProjectManager.getDefault().clearNonProjectCache(); // #41882

        OpenProjectListSettings opls = OpenProjectListSettings.getInstance();
        JFileChooser chooser = new ProjectFileChooser();
        chooser.setFileSelectionMode( JFileChooser.DIRECTORIES_ONLY );

        if ("GTK".equals(javax.swing.UIManager.getLookAndFeel().getID())) { // NOI18N
            // see BugTraq #5027268
            chooser.putClientProperty("GTKFileChooser.showDirectoryIcons", Boolean.TRUE); // NOI18N
            //chooser.putClientProperty("GTKFileChooser.showFileIcons", Boolean.TRUE); // NOI18N
        }

        chooser.setApproveButtonText( NbBundle.getMessage( ProjectChooserAccessory.class, "BTN_PrjChooser_ApproveButtonText" ) ); // NOI18N
        chooser.setApproveButtonMnemonic( NbBundle.getMessage( ProjectChooserAccessory.class, "MNM_PrjChooser_ApproveButtonText" ).charAt (0) ); // NOI18N
        chooser.setApproveButtonToolTipText (NbBundle.getMessage( ProjectChooserAccessory.class, "BTN_PrjChooser_ApproveButtonTooltipText")); // NOI18N
        // chooser.setMultiSelectionEnabled( true );
        chooser.setDialogTitle( NbBundle.getMessage( ProjectChooserAccessory.class, "LBL_PrjChooser_Title" ) ); // NOI18N
        //#61789 on old macosx (jdk 1.4.1) these two method need to be called in this order.
        chooser.setAcceptAllFileFilterUsed( false );
        chooser.setFileFilter( ProjectDirFilter.INSTANCE );

        // A11Y
        chooser.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(ProjectChooserAccessory.class, "AN_ProjectChooserAccessory"));
        chooser.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(ProjectChooserAccessory.class, "AD_ProjectChooserAccessory"));


        if ( defaultAccessory ) {
            chooser.setAccessory(new ProjectChooserAccessory(chooser, opls.isOpenSubprojects()));
        }

        File currDir = null;
        String dir = opls.getLastOpenProjectDir();
        if ( dir != null ) {
            File d = new File( dir );
            if ( d.exists() && d.isDirectory() ) {
                currDir = d;
            }
        }

        FileUtil.preventFileChooserSymlinkTraversal(chooser, currDir);
        new ProjectFileView(chooser);

        return chooser;

    }

    @Override
    public void removeNotify() { // #72006
        super.removeNotify();
        if (modelUpdater != null) { // #101286 - might be already null
            modelUpdater.cancel();
        }
        if (updateSubprojectsTask != null) {
            updateSubprojectsTask.cancel();
        }

        if (displayNameTask != null) {
            displayNameTask.cancel();
        }

        modelUpdater = null;
        subprojectsCache = null;
        updateSubprojectsTask = null;
        displayNameTask = null;
    }

    // Aditional innerclasses for the file chooser -----------------------------

    private static class ProjectFileChooser extends JFileChooser {

        @Override
        public void approveSelection() {
            File selectedFile = getSelectedFile();
            if (selectedFile != null) {
                File dir = FileUtil.normalizeFile(selectedFile);
                FileObject fo = FileUtil.toFileObject(dir);
                if (fo != null && fo.isFolder() && ProjectManager.getDefault().isProject(fo)) {
                    super.approveSelection();
                }
                else {
                    setCurrentDirectory( dir );
                }
            }
        }


    }

    private static class ProjectDirFilter extends FileFilter {

        private static final FileFilter INSTANCE = new ProjectDirFilter( );

        @Override
        public boolean accept( File f ) {

            if ( f.isDirectory() ) {
                //#114765
                if ("CVS".equalsIgnoreCase(f.getName()) && new File(f, "Entries").exists()) { //NOI18N
                    return false;
                }
                return true; // Directory selected
            }

            return false;
        }

        @Override
        public String getDescription() {
            return NbBundle.getMessage( ProjectDirFilter.class, "LBL_PrjChooser_ProjectDirectoryFilter_Name" ); // NOI18N
        }

    }

    private static class ProjectFileView extends FileView implements Runnable {

        private final JFileChooser chooser;
        private final Map<File,Icon> knownProjectIcons = new HashMap<File,Icon>();
        private final RequestProcessor.Task task = Hacks.RP.create(this);
        private File lookingForIcon;

        public ProjectFileView(JFileChooser chooser) {
            this.chooser = chooser;
            chooser.setFileView(this);
            task.setPriority(Thread.MIN_PRIORITY);
        }

        @Override
        public Icon getIcon(File f) {
            if(f == null) {
                // avoid NPE issue #268498
                return null;
            }
            synchronized (this) { //#233480 to reduce number of calls to IO layer
                Icon icon = knownProjectIcons.get(f);
                if (icon != null) {
                    return icon;
                }
            }
            if ( 
                   !f.toString().matches("/[^/]+") && // Unix: /net, /proc, etc.
                    f.getParentFile() != null) { // #173958: do not call ProjectManager.isProject now, could block
                synchronized (this) {
                    if (lookingForIcon == null) {
                        lookingForIcon = f;
                        task.schedule(20);
                        // Only calculate one at a time.
                        // When the view refreshes, the next unknown icon
                        // should trigger the task to be reloaded.
                    }
                }
            }
            try {
                return chooser.getFileSystemView().getSystemIcon(f);
            } catch (NullPointerException ex) {
                //#159646: Workaround for JDK issue #6357445
                // Can happen when a file was deleted on disk while project
                // dialog was still open. In that case, throws an exception
                // repeatedly from FSV.gSI during repaint.
                return null;
            }
        }

        public @Override void run() {
            if (!lookingForIcon.isDirectory()) {
                synchronized (this) {
                    lookingForIcon = null;
                }
                return;
            }
            File d = FileUtil.normalizeFile(lookingForIcon);
            ProjectManager.Result r = getProjectResult(d);
            Icon icon;
            if (r != null) {
                icon = r.getIcon();
                if (icon == null) {
                    Project p = getProject(d);
                    if (p != null) {
                        icon = ProjectUtils.getInformation(p).getIcon();
                    } else {
                        icon = chooser.getFileSystemView().getSystemIcon(lookingForIcon);
                    }
                }
            } else {
                try {
                    icon = chooser.getFileSystemView().getSystemIcon(lookingForIcon);
                } catch (NullPointerException ex) {
                    //#159646: Workaround for JDK issue #6357445
                    // Can happen when a file was deleted on disk while project
                    // dialog was still open. In that case, throws an exception
                    // repeatedly from FSV.gSI during repaint.
                    icon = null;
                }
            }
            synchronized (this) {
                knownProjectIcons.put(lookingForIcon, icon);
                lookingForIcon = null;
            }
            chooser.repaint();
        }

    }

    class ModelUpdater implements Runnable, Cancellable { //#101227 -> non-private
        // volatile Project project;
        volatile List<Project> projects;
        private DefaultListModel subprojectsToSet;
        private boolean cancel = false;

        @Override
        public void run() {

            if ( !SwingUtilities.isEventDispatchThread() ) {
                if (cancel) {
                    return;
                }
                List<Project> currentProjects = projects;
                if ( currentProjects == null ) {
                    return;
                }
                Map<Project,Set<? extends Project>> cache = subprojectsCache;
                if (cache == null) {
                    return;
                }

                jListSubprojects.setListData (new String [] {NbBundle.getMessage (ProjectChooserAccessory.class, "MSG_PrjChooser_WaitMessage")});

                List<Project> subprojects = new ArrayList<Project>(currentProjects.size() * 5);
                for (Project p : currentProjects) {
                    if (cancel) {
                        return;
                    }
                    addSubprojects(p, subprojects, cache); // Find the projects recursively
                }

                if (cancel) {
                    return;
                }
                List<String> subprojectNames = new ArrayList<String>(subprojects.size());
                if ( !subprojects.isEmpty() ) {
                    String pattern = NbBundle.getMessage( ProjectChooserAccessory.class, "LBL_PrjChooser_SubprojectName_Format" ); // NOI18N
                    File pDir = currentProjects.size() == 1 ?
                                FileUtil.toFile( currentProjects.get(0).getProjectDirectory() ) :
                                null;

                    // Replace projects in the list with formated names
                    for (Project p : subprojects) {
                        if (cancel) {
                            return;
                        }
                        FileObject spDir = p.getProjectDirectory();

                        // Try to compute relative path
                        String relPath = null;
                        if ( pDir != null ) { // If only one project is selected
                            relPath = relativizePath(pDir, FileUtil.toFile( spDir ));
                        }

                        if (relPath == null) {
                            // Cannot get a relative path; display it as absolute.
                            relPath = FileUtil.getFileDisplayName(spDir);
                        }
                        String displayName = MessageFormat.format(
                            pattern,
                            ProjectUtils.getInformation(p).getDisplayName(),
                            relPath);
                        subprojectNames.add(displayName);
                    }

                    // Sort the list
                    Collections.sort( subprojectNames, Collator.getInstance() );
                }
                if (currentProjects != projects || cancel) {
                    return;
                }
                DefaultListModel listModel = new DefaultListModel();
                // Put all the strings into the list model
                for (String displayName : subprojectNames) {
                    listModel.addElement(displayName);
                }
                subprojectsToSet = listModel;
                if (cancel) {
                    return;
                }
                SwingUtilities.invokeLater( this );
                return;
            }
            else {
                if ( projects == null ) {
                    ListModel spListModel = jListSubprojects.getModel();
                    if (spListModel instanceof DefaultListModel) {
                        ((DefaultListModel)spListModel).clear();
                    } else {
                        jListSubprojects.setListData (new String[0]);
                    }
                    jCheckBoxSubprojects.setEnabled( false );
                }
                else {
                    jListSubprojects.setModel(subprojectsToSet);
                    // If no soubprojects checkbox should be disabled
                    jCheckBoxSubprojects.setEnabled( !subprojectsToSet.isEmpty() );
                    projects = null;
                }
            }

        }
        
        /** Gets all subprojects recursively
         */
        void addSubprojects(Project p, List<Project> result, Map<Project,Set<? extends Project>> cache) {
            if (cancel) {
                return;
            }
            Set<? extends Project> subprojects = cache.get(p);
            boolean recurse = true;
            if (subprojects == null) {
                ProjectContainerProvider pcp = p.getLookup().lookup(ProjectContainerProvider.class);
                if (pcp != null) {
                    ProjectContainerProvider.Result res = pcp.getContainedProjects();
                    if (res.isRecursive()) {
                        recurse = false;
                    }
                    if (cancel) {
                        return;
                    }
                    subprojects = res.getProjects();
                } else {
                    SubprojectProvider spp = p.getLookup().lookup(SubprojectProvider.class);
                    if (spp != null) {
                        if (cancel) {
                            return;
                        }
                        subprojects = spp.getSubprojects();
                        
                    } else {
                        subprojects = Collections.emptySet();
                    }
                }
                cache.put(p, subprojects);
            }
            for (Project sp : subprojects) {
                if (cancel) {
                    return;
                }
                if ( !result.contains( sp ) ) {
                    result.add( sp );
                    if (recurse) {
                        //#70029: only add sp's subprojects if sp is not already in result,
                        //to prevent StackOverflow caused by misconfigured projects:
                        addSubprojects(sp, result, cache);
                    }
                }
            }

        }
        

        @Override
        public boolean cancel() {
            cancel = true;
            // we don't really care that much to wait for cancelation here..
            return true;
        }


    }


}
