[hg] main-silver: reducing team direct dependencies on project U...

  • From: Tomas Pavek < >
  • To: , , ,
  • Subject: [hg] main-silver: reducing team direct dependencies on project U...
  • Date: Fri, 21 Jun 2013 04:47:24 -0700

changeset 82bc3924ac41 in main-silver ((none))
details: http://hg.netbeans.org/main-silver/rev/82bc3924ac41
description:
        reducing team direct dependencies on project UI, favorites, etc

diffstat:

 bugtracking.bridge/manifest.mf                                               
                       |    3 +-
 bugtracking.bridge/nbproject/project.xml                                     
                       |   11 +-
 
bugtracking.bridge/src/org/netbeans/modules/bugtracking/bridge/ideservices/IDEServicesImpl.java
     |   22 +
 
bugtracking.bridge/src/org/netbeans/modules/bugtracking/bridge/ideservices/ProjectServicesImpl.java
 |  293 +++++++++-
 favorites/manifest.mf                                                        
                       |    2 +-
 favorites/nbproject/project.xml                                              
                       |    2 +-
 kenai.ui/manifest.mf                                                         
                       |    2 +-
 kenai.ui/nbproject/project.xml                                               
                       |    4 +-
 kenai.ui/src/org/netbeans/modules/kenai/ui/SourceAccessorImpl.java           
                       |  125 +---
 kenai.ui/src/org/netbeans/modules/kenai/ui/SourceHandleImpl.java             
                       |  178 +++---
 odcs.versioning/manifest.mf                                                  
                       |    3 +-
 odcs.versioning/nbproject/project.xml                                        
                       |   23 +-
 
odcs.versioning/src/org/netbeans/modules/odcs/versioning/SourceAccessorImpl.java
                    |  122 +---
 
odcs.versioning/src/org/netbeans/modules/odcs/versioning/SourceHandleImpl.java
                      |  218 +++---
 projectui/nbproject/project.properties                                       
                       |    2 +-
 projectui/nbproject/project.xml                                              
                       |    2 -
 team.ui.util/manifest.mf                                                     
                       |    3 +-
 team.ui.util/nbproject/project.xml                                           
                       |    1 +
 team.ui.util/src/org/netbeans/modules/team/ide/spi/IDEProject.java           
                       |  143 ++++
 team.ui.util/src/org/netbeans/modules/team/ide/spi/IDEServices.java          
                       |   34 +-
 team.ui.util/src/org/netbeans/modules/team/ide/spi/ProjectServices.java      
                       |   41 +
 team.ui/manifest.mf                                                          
                       |    2 +-
 team.ui/nbproject/project.xml                                                
                       |   19 +-
 team.ui/src/org/netbeans/modules/team/ui/common/NbProjectHandleImpl.java     
                       |  178 ------
 team.ui/src/org/netbeans/modules/team/ui/common/NbProjectNode.java           
                       |    7 +-
 team.ui/src/org/netbeans/modules/team/ui/common/RecentProjectsCache.java     
                       |   88 ---
 team.ui/src/org/netbeans/modules/team/ui/common/SourceListNode.java          
                       |    9 +-
 team.ui/src/org/netbeans/modules/team/ui/spi/NbProjectHandle.java            
                       |   67 --
 team.ui/src/org/netbeans/modules/team/ui/spi/SourceAccessor.java             
                       |    9 +-
 team.ui/src/org/netbeans/modules/team/ui/spi/SourceHandle.java               
                       |    6 +-
 30 files changed, 802 insertions(+), 817 deletions(-)

diffs (2374 lines):

diff --git a/bugtracking.bridge/manifest.mf b/bugtracking.bridge/manifest.mf
--- a/bugtracking.bridge/manifest.mf
+++ b/bugtracking.bridge/manifest.mf
@@ -3,5 +3,4 @@
 OpenIDE-Module: org.netbeans.modules.bugtracking.bridge
 OpenIDE-Module-Layer: org/netbeans/modules/bugtracking/bridge/layer.xml
 OpenIDE-Module-Localizing-Bundle: 
org/netbeans/modules/bugtracking/bridge/Bundle.properties
-OpenIDE-Module-Specification-Version: 1.28
-
+OpenIDE-Module-Specification-Version: 1.29
diff --git a/bugtracking.bridge/nbproject/project.xml 
b/bugtracking.bridge/nbproject/project.xml
--- a/bugtracking.bridge/nbproject/project.xml
+++ b/bugtracking.bridge/nbproject/project.xml
@@ -124,7 +124,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>1.4</specification-version>
+                        <specification-version>1.7</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -224,6 +224,15 @@
                         <specification-version>6.24</specification-version>
                     </run-dependency>
                 </dependency>
+                <dependency>
+                    
<code-name-base>org.netbeans.modules.favorites</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>1</release-version>
+                        <specification-version>1.36</specification-version>
+                    </run-dependency>
+                </dependency>
             </module-dependencies>
             <test-dependencies>
                 <test-type>
diff --git 
a/bugtracking.bridge/src/org/netbeans/modules/bugtracking/bridge/ideservices/IDEServicesImpl.java
 
b/bugtracking.bridge/src/org/netbeans/modules/bugtracking/bridge/ideservices/IDEServicesImpl.java
--- 
a/bugtracking.bridge/src/org/netbeans/modules/bugtracking/bridge/ideservices/IDEServicesImpl.java
+++ 
b/bugtracking.bridge/src/org/netbeans/modules/bugtracking/bridge/ideservices/IDEServicesImpl.java
@@ -62,6 +62,7 @@
 import org.netbeans.api.java.classpath.GlobalPathRegistry;
 import org.netbeans.api.jumpto.type.TypeBrowser;
 import org.netbeans.modules.autoupdate.ui.api.PluginManager;
+import org.netbeans.modules.favorites.api.Favorites;
 import org.netbeans.modules.team.ide.spi.IDEServices;
 import org.netbeans.modules.versioning.util.SearchHistorySupport;
 import org.netbeans.spi.jumpto.type.TypeDescriptor;
@@ -76,6 +77,7 @@
 import org.openide.text.NbDocument;
 import org.openide.util.HelpCtx;
 import org.openide.util.NbBundle;
+import org.openide.windows.WindowManager;
 
 /**
  *
@@ -251,6 +253,26 @@
         return new SwingXBusyIcon();
     }
 
+    @Override
+    public boolean canOpenInFavorites() {
+        return true;
+    }
+
+    @Override
+    public void openInFavorites(File workingDir) {
+        
WindowManager.getDefault().findTopComponent("favorites").requestActive(); // 
NOI18N
+        try {
+            FileObject fo = FileUtil.toFileObject(workingDir);
+            Favorites.getDefault().selectWithAddition(fo);
+        } catch (IOException ex) {
+            
Logger.getLogger(IDEServicesImpl.class.getName()).log(Level.FINE, 
ex.getMessage(), ex);
+        } catch (IllegalArgumentException ex) {
+            
Logger.getLogger(IDEServicesImpl.class.getName()).log(Level.FINE, 
ex.getMessage(), ex);
+        } catch (NullPointerException ex) {
+            
Logger.getLogger(IDEServicesImpl.class.getName()).log(Level.FINE, 
ex.getMessage(), ex);
+        }
+    }
+
     private static class SwingXBusyIcon extends PainterIcon implements 
BusyIcon {
         private static final int SIZE = 16;
         private static final int POINTS = 8;
diff --git 
a/bugtracking.bridge/src/org/netbeans/modules/bugtracking/bridge/ideservices/ProjectServicesImpl.java
 
b/bugtracking.bridge/src/org/netbeans/modules/bugtracking/bridge/ideservices/ProjectServicesImpl.java
--- 
a/bugtracking.bridge/src/org/netbeans/modules/bugtracking/bridge/ideservices/ProjectServicesImpl.java
+++ 
b/bugtracking.bridge/src/org/netbeans/modules/bugtracking/bridge/ideservices/ProjectServicesImpl.java
@@ -42,18 +42,42 @@
 
 package org.netbeans.modules.bugtracking.bridge.ideservices;
 
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.io.File;
+import java.io.IOException;
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
+import java.net.URISyntaxException;
+import java.net.URL;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.concurrent.Callable;
+import javax.swing.Icon;
+import javax.swing.JFileChooser;
 import org.netbeans.api.project.FileOwnerQuery;
 import org.netbeans.api.project.Project;
+import org.netbeans.api.project.ProjectInformation;
+import org.netbeans.api.project.ProjectManager;
+import org.netbeans.api.project.ProjectUtils;
 import org.netbeans.api.project.ui.OpenProjects;
+import org.netbeans.modules.team.ide.spi.IDEProject;
 import org.netbeans.modules.team.ide.spi.ProjectServices;
-import static org.netbeans.modules.bugtracking.util.BugtrackingUtil.getFile;
+import org.netbeans.spi.project.ui.support.ProjectChooser;
+import org.openide.explorer.ExplorerManager;
+import org.openide.filesystems.FileChangeAdapter;
+import org.openide.filesystems.FileEvent;
 import org.openide.filesystems.FileObject;
+import org.openide.filesystems.FileUtil;
 import org.openide.nodes.Node;
+import org.openide.util.Exceptions;
 import org.openide.util.Lookup;
+import org.openide.windows.TopComponent;
+import org.openide.windows.WindowManager;
 
 /**
  *
@@ -62,6 +86,13 @@
 
@org.openide.util.lookup.ServiceProvider(service=org.netbeans.modules.team.ide.spi.ProjectServices.class)
 public class ProjectServicesImpl implements ProjectServices {
 
+    /** Listener on OpenProjects, bridging to the registered 
IDEProject.OpenListener listeners. */
+    private static ProjectOpenListener projectOpenListener;
+
+    /** Registered listeners from the UI of team project sources. Notified 
when
+     * new projects get opened. */
+    private static List<Reference<IDEProject.OpenListener>> 
ideProjectOpenListeners;
+
     @Override
     public FileObject[] getOpenProjectsDirectories() {
         Project[] openProjects = OpenProjects.getDefault().getOpenProjects();
@@ -108,4 +139,264 @@
         return operation.call();
     }
     
+    @Override
+    public boolean openProject(URL url) {
+        Project p = getProject(url);
+        if (p == null) {
+            return false;
 }
+        OpenProjects.getDefault().open(new Project[] { p }, false);
+        TopComponent projectsTC = 
WindowManager.getDefault().findTopComponent("projectTabLogical_tc"); // NOI18N
+        projectsTC.requestActive();
+        ExplorerManager em = ((ExplorerManager.Provider) 
projectsTC).getExplorerManager();
+
+        Node root = em.getRootContext();
+        Node projNode = null;
+        for (Node n : root.getChildren().getNodes()) {
+            Project prj = n.getLookup().lookup(Project.class);
+            if (prj != null && 
prj.getProjectDirectory().equals(p.getProjectDirectory())) {
+                projNode = n;
+                break;
+            }
+        }
+        if (projNode == null) { // fallback
+            projNode = 
root.getChildren().findChild(ProjectUtils.getInformation(p).getName());
+        }
+        if (projNode != null) {
+            try {
+                em.setSelectedNodes(new Node[] { projNode });
+            } catch (Exception ignore) { // may ignore it
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public void openOtherProject(File workingDir) {
+        ProjectChooser.setProjectsFolder(workingDir);
+        JFileChooser chooser = ProjectChooser.projectChooser();
+        chooser.setCurrentDirectory(workingDir);
+        chooser.setMultiSelectionEnabled(true);
+
+        int option = 
chooser.showOpenDialog(WindowManager.getDefault().getMainWindow());
+        if (option == JFileChooser.APPROVE_OPTION) {
+            final File[] projectDirs;
+            if (chooser.isMultiSelectionEnabled()) {
+                projectDirs = chooser.getSelectedFiles();
+            } else {
+                projectDirs = new File[] { chooser.getSelectedFile() };
+            }
+
+            ArrayList<Project> projects = new 
ArrayList<Project>(projectDirs.length);
+            for (File d : projectDirs) {
+                try {
+                    Project p = 
ProjectManager.getDefault().findProject(FileUtil.toFileObject(d));
+                    if (p != null) {
+                        projects.add(p);
+                    }
+                } catch (IOException ex) {
+                    Exceptions.printStackTrace(ex);
+                } catch (IllegalArgumentException ex) {
+                    Exceptions.printStackTrace(ex);
+                }
+            }
+
+            if (!projects.isEmpty()) {
+                OpenProjects.getDefault().open(projects.toArray(new 
Project[projects.size()]), false);
+            }
+            
WindowManager.getDefault().findTopComponent("projectTabLogical_tc").requestActive();
 // NOI18N
+        }
+    }
+
+    @Override
+    public IDEProject getIDEProject(URL url) {
+        Project p = getProject(url);
+        return p != null ? createIDEProject(p) : null;
+    }
+
+    @Override
+    public IDEProject[] getOpenProjects() {
+        Project[] openProjects = OpenProjects.getDefault().getOpenProjects();
+        IDEProject[] ideProjects = new IDEProject[openProjects.length];
+        for (int i=0; i < openProjects.length; i++) {
+            ideProjects[i] = createIDEProject(openProjects[i]);
+        }
+        return ideProjects;
+    }
+
+    private static Project getProject(URL url) {
+        try {
+            return FileOwnerQuery.getOwner(url.toURI());
+        } catch (URISyntaxException ex) {
+            Exceptions.printStackTrace(ex);
+            return null;
+        }
+    }
+
+    private static IDEProject createIDEProject(Project p) {
+        ProjectInformation pi = ProjectUtils.getInformation(p);
+        return new NbProject(pi.getDisplayName(), pi.getIcon(), 
p.getProjectDirectory().toURL());
+    }
+
+    @Override
+    public synchronized void addProjectOpenListener(IDEProject.OpenListener 
listener) {
+        if (ideProjectOpenListeners == null) {
+            ideProjectOpenListeners = new 
LinkedList<Reference<IDEProject.OpenListener>>();
+        } else {
+            Iterator<Reference<IDEProject.OpenListener>> it = 
ideProjectOpenListeners.iterator();
+            while (it.hasNext()) {
+                Reference<IDEProject.OpenListener> r = it.next();
+                IDEProject.OpenListener l = r.get();
+                if (l == null || l == listener) {
+                    it.remove(); // also doing cleanup of GC'ed references
+                }
+            }
+        }
+        ideProjectOpenListeners.add(new 
WeakReference<IDEProject.OpenListener>(listener));
+        if (projectOpenListener == null) {
+            projectOpenListener = new ProjectOpenListener();
+            
OpenProjects.getDefault().addPropertyChangeListener(projectOpenListener);
+        }
+    }
+
+    @Override
+    public synchronized void 
removeProjectOpenListener(IDEProject.OpenListener listener) {
+        if (ideProjectOpenListeners != null) {
+            Iterator<Reference<IDEProject.OpenListener>> it = 
ideProjectOpenListeners.iterator();
+            while (it.hasNext()) {
+                Reference<IDEProject.OpenListener> r = it.next();
+                IDEProject.OpenListener l = r.get();
+                if (l == null || l == listener) {
+                    it.remove(); // also doing cleanup of GC'ed references
+                }
+            }
+            if (ideProjectOpenListeners.isEmpty()) {
+                ideProjectOpenListeners = null;
+                if (projectOpenListener != null) {
+                    
OpenProjects.getDefault().removePropertyChangeListener(projectOpenListener);
+                    projectOpenListener = null;
+                }
+            }
+        }
+    }
+
+    private static synchronized IDEProject.OpenListener[] 
getIDEProjectOpenListeners() {
+        if (ideProjectOpenListeners == null) {
+            return null;
+        }
+        List<IDEProject.OpenListener> listenerList = new 
ArrayList<IDEProject.OpenListener>(ideProjectOpenListeners.size());
+        Iterator<Reference<IDEProject.OpenListener>> it = 
ideProjectOpenListeners.iterator();
+        while (it.hasNext()) {
+            Reference<IDEProject.OpenListener> r = it.next();
+            IDEProject.OpenListener l = r.get();
+            if (l == null) {
+                it.remove(); // also doing cleanup of GC'ed references
+            } else {
+                listenerList.add(l);
+            }
+        }
+        if (ideProjectOpenListeners.isEmpty()) {
+            ideProjectOpenListeners = null;
+            if (projectOpenListener != null) {
+                
OpenProjects.getDefault().removePropertyChangeListener(projectOpenListener);
+                projectOpenListener = null;
+            }
+            return null;
+        }
+        return listenerList.toArray(new 
IDEProject.OpenListener[listenerList.size()]);
+    }
+
+    private static class NbProject extends IDEProject {
+        private ProjectDeleteListener projectDeleteListener;
+
+        NbProject(String displayName, Icon icon, URL url) {
+            super(displayName, icon, url);
+        }
+
+        @Override
+        public synchronized boolean addDeleteListener(DeleteListener l) {
+            boolean added = super.addDeleteListener(l);
+            if (added && projectDeleteListener == null) {
+                Project p = getProject(getURL());
+                if (p != null) {
+                    FileObject projDir = p.getProjectDirectory();
+                    projectDeleteListener = new 
ProjectDeleteListener(projDir.toURL(), this);
+                    projDir.addFileChangeListener(projectDeleteListener);
+                } else {
+                    super.removeDeleteListener(l);
+                    added = false;
+                }
+            }
+            return added;
+        }
+
+        @Override
+        public synchronized boolean removeDeleteListener(DeleteListener l) {
+            boolean removed = super.removeDeleteListener(l);
+            if (removed && getDeleteListeners().isEmpty() && 
projectDeleteListener != null) {
+                Project p = getProject(getURL());
+                if (p != null) {
+                    FileObject projDir = p.getProjectDirectory();
+                    projDir.removeFileChangeListener(projectDeleteListener);
+                    projectDeleteListener = null;
+                }
+            }
+            return removed;
+        }
+    }
+
+    private static class ProjectOpenListener implements 
PropertyChangeListener {
+        @Override
+        public void propertyChange(PropertyChangeEvent evt) {
+            if 
(!OpenProjects.PROPERTY_OPEN_PROJECTS.equals(evt.getPropertyName())
+                    || evt.getNewValue() == null) {
+                return;
+            }
+            IDEProject.OpenListener[] listeners = 
getIDEProjectOpenListeners();
+            if (listeners == null) {
+                return;
+            }
+            Project[] newProjects = (Project[])evt.getNewValue();
+            Project[] oldProjects = (Project[])evt.getOldValue();
+            List<Project> openedList;
+            if (oldProjects == null) {
+                openedList = Arrays.asList(newProjects);
+            } else {
+                openedList = new ArrayList<Project>();
+                openedList.addAll(Arrays.asList(newProjects));
+                openedList.removeAll(Arrays.asList(oldProjects));
+            }
+            if (!openedList.isEmpty()) {
+                IDEProject[] newlyOpened = new IDEProject[openedList.size()];
+                for (int i=0; i < newlyOpened.length; i++) {
+                    newlyOpened[i] = createIDEProject(openedList.get(i));
+                }
+                for (IDEProject.OpenListener l : listeners) {
+                    l.projectsOpened(newlyOpened);
+                }
+            }
+        }
+    }
+
+    private static class ProjectDeleteListener extends FileChangeAdapter {
+        private URL url;
+        private Reference<NbProject> projectRef;
+
+        ProjectDeleteListener(URL url, NbProject ideProject) {
+            this.url = url;
+            this.projectRef = new WeakReference<NbProject>(ideProject);
+        }
+
+        @Override
+        public void fileDeleted(FileEvent fe) {
+            if (fe.getFile().toURL().equals(url)) {
+                NbProject project = projectRef.get();
+                if (project != null) {
+                    project.notifyDeleted();
+                } else {
+                    fe.getFile().removeFileChangeListener(this);
+                }
+            }
+        }
+    }
+}
diff --git a/favorites/manifest.mf b/favorites/manifest.mf
--- a/favorites/manifest.mf
+++ b/favorites/manifest.mf
@@ -1,7 +1,7 @@
 Manifest-Version: 1.0
 OpenIDE-Module: org.netbeans.modules.favorites/1
 OpenIDE-Module-Localizing-Bundle: 
org/netbeans/modules/favorites/Bundle.properties
-OpenIDE-Module-Specification-Version: 1.35
+OpenIDE-Module-Specification-Version: 1.36
 OpenIDE-Module-Layer: org/netbeans/modules/favorites/resources/layer.xml
 AutoUpdate-Show-In-Client: false
 AutoUpdate-Essential-Module: true
diff --git a/favorites/nbproject/project.xml b/favorites/nbproject/project.xml
--- a/favorites/nbproject/project.xml
+++ b/favorites/nbproject/project.xml
@@ -258,7 +258,7 @@
             <friend-packages>
                 <friend>org.netbeans.modules.cnd.remote</friend>
                 <friend>org.netbeans.modules.kenai.ui</friend>
-                <friend>org.netbeans.modules.odcs.versioning</friend>
+                <friend>org.netbeans.modules.bugtracking.bridge</friend>
                 <package>org.netbeans.modules.favorites.api</package>
             </friend-packages>
         </data>
diff --git a/kenai.ui/manifest.mf b/kenai.ui/manifest.mf
--- a/kenai.ui/manifest.mf
+++ b/kenai.ui/manifest.mf
@@ -3,4 +3,4 @@
 OpenIDE-Module: org.netbeans.modules.kenai.ui
 OpenIDE-Module-Localizing-Bundle: 
org/netbeans/modules/kenai/ui/Bundle.properties
 OpenIDE-Module-Layer: org/netbeans/modules/kenai/ui/resources/layer.xml
-OpenIDE-Module-Specification-Version: 1.11
+OpenIDE-Module-Specification-Version: 1.12
diff --git a/kenai.ui/nbproject/project.xml b/kenai.ui/nbproject/project.xml
--- a/kenai.ui/nbproject/project.xml
+++ b/kenai.ui/nbproject/project.xml
@@ -167,7 +167,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>1.11</specification-version>
+                        <specification-version>1.12</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -175,7 +175,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>1.0</specification-version>
+                        <specification-version>1.7</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
diff --git 
a/kenai.ui/src/org/netbeans/modules/kenai/ui/SourceAccessorImpl.java 
b/kenai.ui/src/org/netbeans/modules/kenai/ui/SourceAccessorImpl.java
--- a/kenai.ui/src/org/netbeans/modules/kenai/ui/SourceAccessorImpl.java
+++ b/kenai.ui/src/org/netbeans/modules/kenai/ui/SourceAccessorImpl.java
@@ -42,42 +42,27 @@
 
 package org.netbeans.modules.kenai.ui;
 
-import org.netbeans.modules.team.ui.common.NbProjectHandleImpl;
 import java.awt.event.ActionEvent;
-import java.io.File;
-import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.logging.Level;
-import java.util.logging.Logger;
 import javax.swing.AbstractAction;
 import javax.swing.Action;
-import javax.swing.JFileChooser;
-import org.netbeans.api.project.Project;
-import org.netbeans.api.project.ProjectManager;
-import org.netbeans.api.project.ProjectUtils;
-import org.netbeans.api.project.ui.OpenProjects;
-import org.netbeans.modules.favorites.api.Favorites;
 import org.netbeans.modules.kenai.api.KenaiException;
 import org.netbeans.modules.kenai.api.KenaiService.Type;
 import org.netbeans.modules.kenai.api.KenaiProject;
 import org.netbeans.modules.kenai.api.KenaiFeature;
-import org.netbeans.modules.kenai.ui.api.KenaiServer;
-import org.netbeans.modules.team.ui.spi.NbProjectHandle;
+import org.netbeans.modules.team.ide.spi.IDEProject;
+import org.netbeans.modules.team.ide.spi.IDEServices;
+import org.netbeans.modules.team.ide.spi.ProjectServices;
 import org.netbeans.modules.team.ui.spi.ProjectHandle;
 import org.netbeans.modules.team.ui.spi.SourceAccessor;
 import org.netbeans.modules.team.ui.spi.SourceHandle;
-import org.netbeans.spi.project.ui.support.ProjectChooser;
-import org.openide.explorer.ExplorerManager;
-import org.openide.filesystems.FileObject;
-import org.openide.filesystems.FileUtil;
-import org.openide.nodes.Node;
 import org.openide.util.Exceptions;
+import org.openide.util.Lookup;
 import org.openide.util.lookup.ServiceProvider;
-import org.openide.windows.WindowManager;
 
 /**
  *
@@ -134,120 +119,40 @@
     }
 
     @Override
-    public Action getDefaultAction(final NbProjectHandle prj) {
+    public Action getDefaultAction(final IDEProject ideProject) {
         return new AbstractAction() {
-
+            @Override
             public void actionPerformed(ActionEvent e) {
-                Project project = ((NbProjectHandleImpl) prj).getProject();
-                if (project == null) {
-                    ((NbProjectHandleImpl) prj).remove();
-                } else {
-                    OpenProjects.getDefault().open(new Project[]{project}, 
false);
-                    
WindowManager.getDefault().findTopComponent("projectTabLogical_tc").requestActive();
 // NOI18N
-                    selectProject(project);
+                ProjectServices projects = 
Lookup.getDefault().lookup(ProjectServices.class);
+                if (!projects.openProject(ideProject.getURL())) {
+                    ideProject.notifyDeleted();
                 }
             }
-
-            private void selectProject(final Project p) {
-                final ExplorerManager em = ((ExplorerManager.Provider) 
WindowManager.getDefault().findTopComponent("projectTabLogical_tc")).getExplorerManager();
 // NOI18N
-
-                Node root = em.getRootContext();
-                // Node projNode = root.getChildren ().findChild( 
p.getProjectDirectory().getName () );
-                Node projNode = null;
-                for (Node n : root.getChildren().getNodes()) {
-                    Project prj = n.getLookup().lookup(Project.class);
-                    if (prj != null && 
prj.getProjectDirectory().equals(p.getProjectDirectory())) {
-                        projNode = n;
-                        break;
-                    }
-                }
-                if (projNode == null) {
-                    // fallback..
-                    projNode = 
root.getChildren().findChild(ProjectUtils.getInformation(p).getName());
-                }
-
-                if (projNode != null) {
-                    try {
-                        em.setSelectedNodes(new Node[]{projNode});
-                    } catch (Exception ignore) {
-                        // may ignore it
-                    }
-                }
-
-            }
         };
     }
 
     @Override
     public Action getOpenOtherAction(final SourceHandle src) {
-
         return new AbstractAction() {
+            @Override
             public void actionPerformed(ActionEvent e) {
-                ProjectChooser.setProjectsFolder(src.getWorkingDirectory());
-                JFileChooser chooser = ProjectChooser.projectChooser();
-                chooser.setMultiSelectionEnabled(true);
-
-                int option = 
chooser.showOpenDialog(WindowManager.getDefault().getMainWindow()); // Sow 
the chooser
-
-                if (option == JFileChooser.APPROVE_OPTION) {
-
-                    final File[] projectDirs;
-                    if (chooser.isMultiSelectionEnabled()) {
-                        projectDirs = chooser.getSelectedFiles();
-                    } else {
-                        projectDirs = new File[]{chooser.getSelectedFile()};
-                    }
-
-                    ArrayList<Project> projects = new 
ArrayList<Project>(projectDirs.length);
-                    for (File d : projectDirs) {
-                        try {
-                            Project p = 
ProjectManager.getDefault().findProject(FileUtil.toFileObject(d));
-                            projects.add(p);
-                        } catch (IOException ex) {
-                            Exceptions.printStackTrace(ex);
-                        } catch (IllegalArgumentException ex) {
-                            Exceptions.printStackTrace(ex);
-                        }
-                    }
-
-                    Project projectsArray[] = new Project[projects.size()];
-                    projects.toArray(projectsArray);
-
-
-                    OpenProjects.getDefault().open(
-                            projectsArray, // Put the project into 
OpenProjectList
-                            false);
-                    
WindowManager.getDefault().findTopComponent("projectTabLogical_tc").requestActive();
 // NOI18N
-                }
+                ProjectServices projects = 
Lookup.getDefault().lookup(ProjectServices.class);
+                projects.openOtherProject(src.getWorkingDirectory());
             }
         };
     }
 
     @Override
     public Action getOpenFavoritesAction(final SourceHandle src) {
-
         return new AbstractAction() {
+            @Override
             public void actionPerformed(ActionEvent e) {
-                
WindowManager.getDefault().findTopComponent("favorites").requestActive(); // 
NOI18N
-                try {
-                    FileObject fo = 
FileUtil.toFileObject(src.getWorkingDirectory());
-                    Favorites.getDefault().selectWithAddition(fo);
-                } catch (IOException ex) {
-                    printStackTrace(ex);
-                } catch (IllegalArgumentException ex) {
-                    printStackTrace(ex);
-                } catch (NullPointerException ex) {
-                    printStackTrace(ex);
-                }
+                IDEServices ide = 
Lookup.getDefault().lookup(IDEServices.class);
+                ide.openInFavorites(src.getWorkingDirectory());
              }
         };
     }
 
-    private static void printStackTrace(Throwable t) {
-        Logger.getLogger(SourceAccessorImpl.class.getName()).log(Level.FINE, 
t.getMessage(), t);
-    }
-
-
     public static class ProjectAndFeature {
 
         public KenaiProject kenaiProject;
diff --git a/kenai.ui/src/org/netbeans/modules/kenai/ui/SourceHandleImpl.java 
b/kenai.ui/src/org/netbeans/modules/kenai/ui/SourceHandleImpl.java
--- a/kenai.ui/src/org/netbeans/modules/kenai/ui/SourceHandleImpl.java
+++ b/kenai.ui/src/org/netbeans/modules/kenai/ui/SourceHandleImpl.java
@@ -42,55 +42,52 @@
 
 package org.netbeans.modules.kenai.ui;
 
-import org.netbeans.modules.team.ui.common.RecentProjectsCache;
-import org.netbeans.modules.team.ui.common.NbProjectHandleImpl;
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
 import java.io.File;
 import java.io.IOException;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
 import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import java.util.prefs.BackingStoreException;
 import java.util.prefs.Preferences;
-import org.netbeans.api.project.Project;
-import org.netbeans.api.project.ui.OpenProjects;
+import org.netbeans.api.queries.VersioningQuery;
 import org.netbeans.modules.kenai.api.KenaiFeature;
 import org.netbeans.modules.kenai.api.KenaiService;
-import org.netbeans.modules.team.ui.spi.NbProjectHandle;
 import org.netbeans.modules.team.ui.spi.SourceHandle;
 import org.netbeans.modules.mercurial.api.Mercurial;
 import org.netbeans.modules.subversion.api.Subversion;
+import org.netbeans.modules.team.ide.spi.IDEProject;
+import org.netbeans.modules.team.ide.spi.ProjectServices;
 import org.netbeans.modules.team.ui.spi.ProjectHandle;
 import org.openide.filesystems.FileObject;
 import org.openide.filesystems.FileUtil;
+import org.openide.filesystems.URLMapper;
 import org.openide.util.Exceptions;
+import org.openide.util.Lookup;
 import org.openide.util.NbPreferences;
 import org.openide.util.RequestProcessor;
-import org.openide.util.WeakListeners;
 
 /**
  *
  * @author Milan Kubec, Jan Becicka
  */
-public class SourceHandleImpl extends SourceHandle implements 
PropertyChangeListener {
+public class SourceHandleImpl extends SourceHandle {
 
     private KenaiFeature feature;
     private Preferences prefs;
     private ProjectHandle projectHandle;
+    private final List<IDEProject> recent = new LinkedList<IDEProject>();
     private static final int MAX_PROJECTS = 5;
     private static final String RECENTPROJECTS_PREFIX = "recent.projects."; 
// NOI18N
     private String externalScmType=SCM_TYPE_UNKNOWN;
     public static final String SCM_TYPE_UNKNOWN = "unknown";//NOI18N
     public static final String SCM_TYPE_CVS = "cvs";//NOI18N
-    private RequestProcessor rp = new 
RequestProcessor(SourceHandleImpl.class);
+    private IDEProjectListener projectListener = new IDEProjectListener();
+
 
     public String getExternalScmType() {
         return externalScmType;
@@ -111,7 +108,6 @@
             }
         }
         this.projectHandle = projectHandle;
-        
OpenProjects.getDefault().addPropertyChangeListener(WeakListeners.propertyChange(this
 , OpenProjects.getDefault()));
         initRecent();
     }
 
@@ -136,10 +132,9 @@
         return feature.getService();
     }
 
-    List<NbProjectHandle> recent = new ArrayList<NbProjectHandle>();
     @Override
-    public List<NbProjectHandle> getRecentProjects() {
-        return recent;
+    public synchronized List<IDEProject> getRecentProjects() {
+        return new ArrayList<IDEProject>(recent);
     }
 
     @Override
@@ -164,103 +159,93 @@
         }
     }
 
-    public void propertyChange(PropertyChangeEvent evt) {
-        final List<Project> newProjects = 
getNewProjects((Project[])evt.getOldValue(), (Project[])evt.getNewValue());
-        rp.post(new Runnable() {
-            public void run() {
-                addToRecentProjects(newProjects, true);
-            }
-        });
-    }
-
-    void remove(NbProjectHandleImpl aThis) {
-        recent.remove(aThis);
-        storeRecent();
-        projectHandle.firePropertyChange(ProjectHandle.PROP_SOURCE_LIST, 
null, null);
-    }
-
     void refresh() {
         if (projectHandle!=null) {
             projectHandle.firePropertyChange(ProjectHandle.PROP_SOURCE_LIST, 
null, null);
         }
     }
 
-    private synchronized void addToRecentProjects(List<Project> newProjects, 
boolean fireChanges) {
-        for (Project prj : newProjects) {
-            try {
-                if (isUnder(prj.getProjectDirectory())) {
-                    NbProjectHandleImpl nbHandle = 
RecentProjectsCache.getDefault().getProjectHandle(prj, this, removeHandler);
-                    recent.remove(nbHandle);
-                    recent.add(0, nbHandle);
-                    if (recent.size()>MAX_PROJECTS) {
-                        recent.remove(MAX_PROJECTS);
+    private synchronized boolean addToRecent(IDEProject... projects) {
+        boolean changed = false;
+        for (IDEProject ideProject : projects) {
+            boolean alreadyPresent = recent.remove(ideProject);
+            if (alreadyPresent || isUnder(ideProject)) {
+                recent.add(0, ideProject);
+                if (!alreadyPresent) {
+                    ideProject.addDeleteListener(projectListener);
                     }
+                changed = true;
+            }
+        }
+        while (recent.size() > MAX_PROJECTS) {
+            IDEProject ideProject = recent.remove(MAX_PROJECTS);
+            ideProject.removeDeleteListener(projectListener);
+            changed = true;
+        }
+        if (changed) {
                     storeRecent();
-                    if (fireChanges)
-                        
projectHandle.firePropertyChange(ProjectHandle.PROP_SOURCE_LIST, null, null);
                 }
-            } catch (IOException ex) {
-                
Logger.getLogger(SourceHandleImpl.class.getName()).fine("Project not found 
for " + prj);
-            }
-        }
+        return changed;
     }
 
-    private List<Project> getNewProjects(Project[] old, Project[] newp) {
-        if (newp == null) {
-            return Collections.emptyList();
-        } else if (old == null) {
-            return Arrays.asList(newp);
+    private synchronized boolean removeFromRecent(IDEProject ideProject) {
+        boolean removed = recent.remove(ideProject);
+        if (removed) {
+            ideProject.removeDeleteListener(projectListener);
+            storeRecent();
         }
-        List result = new ArrayList();
-        result.addAll(Arrays.asList(newp));
-        result.removeAll(Arrays.asList(old));
-        return result;
+        return removed;
     }
 
     private File guessWorkdir() {
-        if (recent.isEmpty()) {
+        URL url = null;
+        synchronized(this) {
+            if (!recent.isEmpty()) {
+                url = recent.get(0).getURL();
+            }
+        }
+        if (url != null) {
+            FileObject projectDirectory = URLMapper.findFileObject(url);
+            if (projectDirectory != null) {
+                FileObject parent = projectDirectory.getParent();
+                if (parent != null && parent.isValid()) {
+                    return FileUtil.toFile(parent);
+                }
+            }
+        }
             return null;
         }
-        try {
-            final FileObject parent = ((NbProjectHandleImpl) 
recent.iterator().next()).getProject().getProjectDirectory().getParent();
-            if (parent.isValid())
-                return FileUtil.toFile(parent);
-            return null;
-        } catch (Throwable t) {
-            return null;
-        }
-    }
 
     private void initRecent() {
         if (prefs==null) {
             //external repository not supported
             return;
         }
+
+        ProjectServices projects = 
Lookup.getDefault().lookup(ProjectServices.class);
+        if (projects == null) {
+            return;
+        }
+
         List<String> roots = getStringList(prefs, RECENTPROJECTS_PREFIX + 
feature.getLocation());
         for (String root:roots) {
             try {
-                NbProjectHandleImpl nbH = 
RecentProjectsCache.getDefault().getProjectHandle(new URL(root), this, 
removeHandler);
-                if (nbH!=null)
-                    recent.add(nbH);
+                IDEProject ideProject = projects.getIDEProject(new 
URL(root));
+                if (ideProject != null) {
+                    recent.add(ideProject); // 'recent' not yet available 
outside, does not have to by synchronized here
+                    ideProject.addDeleteListener(projectListener);
+                }
             } catch (IOException ex) {
                 
Logger.getLogger(SourceHandleImpl.class.getName()).fine("Project not found 
for " + root);
             }
         }
-        int count = recent.size();
-        List list = new LinkedList();
-        final Project[] openProjects = 
OpenProjects.getDefault().getOpenProjects();
-        for (int i=0;count<MAX_PROJECTS && i<openProjects.length;i++) {
-            if (isUnder(openProjects[i].getProjectDirectory())) {
-                list.add(openProjects[i]);
-                count++;
-            }
+        projects.addProjectOpenListener(projectListener);
+        addToRecent(projects.getOpenProjects());
         }
         
-        addToRecentProjects(list, false);
-    }
-
-    private boolean isUnder(FileObject projectDirectory) {
-        String remoteLocation = (String) 
projectDirectory.getAttribute("ProvidedExtensions.RemoteLocation"); // NOI18N
+    private boolean isUnder(IDEProject ideProject) {
+        FileObject projectDirectory = 
URLMapper.findFileObject(ideProject.getURL());
+        String remoteLocation = projectDirectory != null ? 
VersioningQuery.getRemoteLocation(projectDirectory.toURI()) : null;
         String location = feature.getLocation();
         if (!location.endsWith("/")) {//NOI18N
             location+="/";//NOI18N
@@ -284,14 +269,14 @@
     }
 
     private void storeRecent() {
+        if (prefs != null) {
         List<String> value = new ArrayList<String>();
-        for (NbProjectHandle nbp:recent) {
-            value.add(((NbProjectHandleImpl) nbp).getUrl());
+            for (IDEProject prj : recent) {
+                value.add(prj.getURL().toString());
         }
-        if (prefs!=null)
             putStringList(prefs, RECENTPROJECTS_PREFIX + 
feature.getLocation(), value);
     }
-
+    }
 
     /*
      * Helper method to get an array of Strings from preferences.
@@ -350,10 +335,25 @@
         }
     }
     
-    private NbProjectHandleImpl.RemoveHandler removeHandler = new 
NbProjectHandleImpl.RemoveHandler() {
+    private class IDEProjectListener implements IDEProject.OpenListener, 
IDEProject.DeleteListener {
+        private RequestProcessor rp = new 
RequestProcessor(SourceHandleImpl.class);
+
         @Override
-        public void remove(NbProjectHandleImpl nbProjectHandle) {
-            SourceHandleImpl.this.remove(nbProjectHandle);
+        public void projectsOpened(final IDEProject[] projects) {
+            rp.post(new Runnable() { // in RP because of bug 179082
+                @Override
+                public void run() {
+                    addToRecent(projects);
+                    refresh();
         }
-    };
+            });
 }
+
+        @Override
+        public void projectDeleted(IDEProject prj) {
+            if (removeFromRecent(prj)) {
+                refresh();
+            }
+        }
+    }
+}
diff --git a/odcs.versioning/manifest.mf b/odcs.versioning/manifest.mf
--- a/odcs.versioning/manifest.mf
+++ b/odcs.versioning/manifest.mf
@@ -1,5 +1,4 @@
 Manifest-Version: 1.0
 OpenIDE-Module: org.netbeans.modules.odcs.versioning
 OpenIDE-Module-Localizing-Bundle: 
org/netbeans/modules/odcs/versioning/Bundle.properties
-OpenIDE-Module-Specification-Version: 1.0
-
+OpenIDE-Module-Specification-Version: 1.1
diff --git a/odcs.versioning/nbproject/project.xml 
b/odcs.versioning/nbproject/project.xml
--- a/odcs.versioning/nbproject/project.xml
+++ b/odcs.versioning/nbproject/project.xml
@@ -22,12 +22,12 @@
                     </run-dependency>
                 </dependency>
                 <dependency>
-                    
<code-name-base>org.netbeans.modules.favorites</code-name-base>
+                    
<code-name-base>org.netbeans.modules.queries</code-name-base>
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
                         <release-version>1</release-version>
-                        <specification-version>1.30</specification-version>
+                        <specification-version>1.35</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -40,15 +40,6 @@
                     </run-dependency>
                 </dependency>
                 <dependency>
-                    
<code-name-base>org.netbeans.modules.projectuiapi</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <release-version>1</release-version>
-                        <specification-version>1.58</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
                     
<code-name-base>org.netbeans.modules.odcs</code-name-base>
                     <build-prerequisite/>
                     <compile-dependency/>
@@ -65,11 +56,19 @@
                     </run-dependency>
                 </dependency>
                 <dependency>
+                    
<code-name-base>org.netbeans.modules.team.ui.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.7</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
                     
<code-name-base>org.netbeans.modules.team.ui</code-name-base>
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>0.1</specification-version>
+                        <specification-version>1.12</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
diff --git 
a/odcs.versioning/src/org/netbeans/modules/odcs/versioning/SourceAccessorImpl.java
 
b/odcs.versioning/src/org/netbeans/modules/odcs/versioning/SourceAccessorImpl.java
--- 
a/odcs.versioning/src/org/netbeans/modules/odcs/versioning/SourceAccessorImpl.java
+++ 
b/odcs.versioning/src/org/netbeans/modules/odcs/versioning/SourceAccessorImpl.java
@@ -58,32 +58,20 @@
 import java.util.logging.Logger;
 import javax.swing.AbstractAction;
 import javax.swing.Action;
-import javax.swing.JFileChooser;
-import org.netbeans.api.project.Project;
-import org.netbeans.api.project.ProjectManager;
-import org.netbeans.api.project.ProjectUtils;
-import org.netbeans.api.project.ui.OpenProjects;
-import org.netbeans.modules.favorites.api.Favorites;
 import org.netbeans.modules.odcs.api.ODCSProject;
 import org.netbeans.modules.odcs.client.api.ODCSException;
 import org.netbeans.modules.odcs.ui.spi.VCSAccessor;
 import org.netbeans.modules.odcs.versioning.spi.ApiProvider;
 import 
org.netbeans.modules.odcs.versioning.spi.ApiProvider.LocalRepositoryInitializer;
-import org.netbeans.modules.team.ui.common.NbProjectHandleImpl;
-import org.netbeans.modules.team.ui.spi.NbProjectHandle;
+import org.netbeans.modules.team.ide.spi.IDEProject;
+import org.netbeans.modules.team.ide.spi.IDEServices;
+import org.netbeans.modules.team.ide.spi.ProjectServices;
 import org.netbeans.modules.team.ui.spi.ProjectHandle;
 import org.netbeans.modules.team.ui.spi.SourceAccessor;
 import org.netbeans.modules.team.ui.spi.SourceHandle;
-import org.netbeans.spi.project.ui.support.ProjectChooser;
-import org.openide.explorer.ExplorerManager;
-import org.openide.filesystems.FileObject;
-import org.openide.filesystems.FileUtil;
-import org.openide.nodes.Node;
-import org.openide.util.Exceptions;
 import org.openide.util.Lookup;
 import org.openide.util.lookup.ServiceProvider;
 import org.openide.util.lookup.ServiceProviders;
-import org.openide.windows.WindowManager;
 
 /**
  *
@@ -120,117 +108,39 @@
     }
 
     @Override
-    public Action getDefaultAction(final NbProjectHandle prj) {
+    public Action getDefaultAction(final IDEProject ideProject) {
         return new AbstractAction() {
-
             @Override
             public void actionPerformed(ActionEvent e) {
-                Project project = ((NbProjectHandleImpl) prj).getProject();
-                if (project == null) {
-                    ((NbProjectHandleImpl) prj).remove();
-                } else {
-                    OpenProjects.getDefault().open(new Project[]{project}, 
false);
-                    
WindowManager.getDefault().findTopComponent("projectTabLogical_tc").requestActive();
 // NOI18N
-                    selectProject(project);
+                ProjectServices projects = 
Lookup.getDefault().lookup(ProjectServices.class);
+                if (!projects.openProject(ideProject.getURL())) {
+                    ideProject.notifyDeleted();
                 }
             }
-
-            private void selectProject(final Project p) {
-                final ExplorerManager em = ((ExplorerManager.Provider) 
WindowManager.getDefault().findTopComponent("projectTabLogical_tc")).getExplorerManager();
 // NOI18N
-
-                Node root = em.getRootContext();
-                // Node projNode = root.getChildren ().findChild( 
p.getProjectDirectory().getName () );
-                Node projNode = null;
-                for (Node n : root.getChildren().getNodes()) {
-                    Project prj = n.getLookup().lookup(Project.class);
-                    if (prj != null && 
prj.getProjectDirectory().equals(p.getProjectDirectory())) {
-                        projNode = n;
-                        break;
-                    }
-                }
-                if (projNode == null) {
-                    // fallback..
-                    projNode = 
root.getChildren().findChild(ProjectUtils.getInformation(p).getName());
-                }
-
-                if (projNode != null) {
-                    try {
-                        em.setSelectedNodes(new Node[]{projNode});
-                    } catch (Exception ignore) {
-                        // may ignore it
-                    }
-                }
-
-            }
         };
     }
 
     @Override
     public Action getOpenOtherAction(final SourceHandle src) {
-
         return new AbstractAction() {
             @Override
             public void actionPerformed(ActionEvent e) {
-                ProjectChooser.setProjectsFolder(src.getWorkingDirectory());
-                JFileChooser chooser = ProjectChooser.projectChooser();
-                chooser.setCurrentDirectory(src.getWorkingDirectory());
-                chooser.setMultiSelectionEnabled(true);
-
-                int option = 
chooser.showOpenDialog(WindowManager.getDefault().getMainWindow()); // Sow 
the chooser
-
-                if (option == JFileChooser.APPROVE_OPTION) {
-
-                    final File[] projectDirs;
-                    if (chooser.isMultiSelectionEnabled()) {
-                        projectDirs = chooser.getSelectedFiles();
-                    } else {
-                        projectDirs = new File[]{chooser.getSelectedFile()};
-                    }
-
-                    ArrayList<Project> projects = new 
ArrayList<Project>(projectDirs.length);
-                    for (File d : projectDirs) {
-                        try {
-                            Project p = 
ProjectManager.getDefault().findProject(FileUtil.toFileObject(d));
-                            projects.add(p);
-                        } catch (IOException ex) {
-                            Exceptions.printStackTrace(ex);
-                        } catch (IllegalArgumentException ex) {
-                            Exceptions.printStackTrace(ex);
-                        }
-                    }
-
-                    Project projectsArray[] = new Project[projects.size()];
-                    projects.toArray(projectsArray);
-
-
-                    OpenProjects.getDefault().open(
-                            projectsArray, // Put the project into 
OpenProjectList
-                            false);
-                    
WindowManager.getDefault().findTopComponent("projectTabLogical_tc").requestActive();
 // NOI18N
-                }
+                ProjectServices projects = 
Lookup.getDefault().lookup(ProjectServices.class);
+                projects.openOtherProject(src.getWorkingDirectory());
             }
         };
     }
 
     @Override
     public Action getOpenFavoritesAction(final SourceHandle src) {
-
-        return new AbstractAction() {
+        final IDEServices ide = 
Lookup.getDefault().lookup(IDEServices.class);
+        return ide.canOpenInFavorites() ?
+            new AbstractAction() {
             @Override
             public void actionPerformed(ActionEvent e) {
-                
WindowManager.getDefault().findTopComponent("favorites").requestActive(); // 
NOI18N
-                try {
-                    FileObject fo = 
FileUtil.toFileObject(src.getWorkingDirectory());
-                    Favorites.getDefault().selectWithAddition(fo);
-                } catch (IOException ex) {
-                    printStackTrace(ex);
-                } catch (IllegalArgumentException ex) {
-                    printStackTrace(ex);
-                } catch (NullPointerException ex) {
-                    printStackTrace(ex);
+                    ide.openInFavorites(src.getWorkingDirectory());
                 }
-             }
-        };
+            } : null;
     }
     
     @Override
@@ -254,10 +164,6 @@
         return action;
     }
 
-    private static void printStackTrace(Throwable t) {
-        Logger.getLogger(SourceAccessorImpl.class.getName()).log(Level.FINE, 
t.getMessage(), t);
-    }
-
     @Override
     public RepositoryInitializer getRepositoryInitializer (String 
repositoryKind) {
         RepositoryInitializer initializer = null;
diff --git 
a/odcs.versioning/src/org/netbeans/modules/odcs/versioning/SourceHandleImpl.java
 
b/odcs.versioning/src/org/netbeans/modules/odcs/versioning/SourceHandleImpl.java
--- 
a/odcs.versioning/src/org/netbeans/modules/odcs/versioning/SourceHandleImpl.java
+++ 
b/odcs.versioning/src/org/netbeans/modules/odcs/versioning/SourceHandleImpl.java
@@ -43,61 +43,58 @@
 package org.netbeans.modules.odcs.versioning;
 
 import com.tasktop.c2c.server.scm.domain.ScmRepository;
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
 import java.io.File;
 import java.io.IOException;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
 import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import java.util.prefs.BackingStoreException;
 import java.util.prefs.Preferences;
-import org.netbeans.api.project.Project;
-import org.netbeans.api.project.ui.OpenProjects;
+import org.netbeans.api.queries.VersioningQuery;
 import org.netbeans.modules.odcs.api.ODCSProject;
-import org.netbeans.modules.team.ui.common.NbProjectHandleImpl;
+import org.netbeans.modules.team.ide.spi.IDEProject;
+import org.netbeans.modules.team.ide.spi.ProjectServices;
 import org.netbeans.modules.team.ui.spi.SourceHandle;
-import org.netbeans.modules.team.ui.common.RecentProjectsCache;
-import org.netbeans.modules.team.ui.spi.NbProjectHandle;
 import org.netbeans.modules.team.ui.spi.ProjectHandle;
 import org.openide.filesystems.FileObject;
 import org.openide.filesystems.FileUtil;
+import org.openide.filesystems.URLMapper;
 import org.openide.util.Exceptions;
+import org.openide.util.Lookup;
 import org.openide.util.NbPreferences;
 import org.openide.util.RequestProcessor;
 import org.openide.util.Utilities;
-import org.openide.util.WeakListeners;
 
 /**
  *
  * @author Milan Kubec, Jan Becicka
  * XXX somebody keeps and leaks the handles
  */
-public class SourceHandleImpl extends SourceHandle implements 
PropertyChangeListener {
+public class SourceHandleImpl extends SourceHandle {
+
+    private static final int MAX_PROJECTS = 5;
+    private static final String RECENTPROJECTS_PREFIX = "recent.projects."; 
// NOI18N
+    public static final String SCM_TYPE_UNKNOWN = "unknown";//NOI18N
+    private static final String WORKINGDIR = "working.dir."; //NOI18N
 
     private ScmRepository repository;
     private Preferences prefs;
     private ProjectHandle<ODCSProject> projectHandle;
-    private static final int MAX_PROJECTS = 5;
-    private static final String RECENTPROJECTS_PREFIX = "recent.projects."; 
// NOI18N
-    public static final String SCM_TYPE_UNKNOWN = "unknown";//NOI18N
-    private static final String WORKINGDIR = "working.dir."; //NOI18N
-    private RequestProcessor rp = new 
RequestProcessor(SourceHandleImpl.class);
+    private final List<IDEProject> recent = new LinkedList<IDEProject>();
     private final boolean supported;
 
+    private IDEProjectListener projectListener = new IDEProjectListener();
+
     public SourceHandleImpl(final ProjectHandle<ODCSProject> projectHandle, 
ScmRepository repository, boolean isSupported) {
         this.repository = repository;
         prefs = NbPreferences.forModule(SourceHandleImpl.class);
         this.projectHandle = projectHandle;
         this.supported = isSupported;
-        
OpenProjects.getDefault().addPropertyChangeListener(WeakListeners.propertyChange(this
 , OpenProjects.getDefault()));
         initRecent();
     }
 
@@ -124,45 +121,34 @@
         return repository.getType().name();
     }
 
-    List<NbProjectHandle> recent = new ArrayList<NbProjectHandle>();
     @Override
-    public List<NbProjectHandle> getRecentProjects() {
-        return recent;
+    public synchronized List<IDEProject> getRecentProjects() {
+        return new ArrayList<IDEProject>(recent);
     }
 
     @Override
     public File getWorkingDirectory() {
+        File wd = null;
+        String uriString = prefs.get(WORKINGDIR + repository.getUrl(), 
null); // NOI18N
         try {
-            String uriString = prefs.get(WORKINGDIR + repository.getUrl(), 
null); // NOI18N
             if (uriString!=null) {
-                return getWorkDir(uriString);
+                wd = getWorkDir(uriString);
             } else if (repository.getAlternateUrl() != null && 
!repository.getAlternateUrl().isEmpty()) {
                 uriString = prefs.get(WORKINGDIR + 
repository.getAlternateUrl(), null);
                 if (uriString != null) {
-                    return getWorkDir(uriString);
+                    wd = getWorkDir(uriString);
                 }
             }
-            return guessWorkdir();
         } catch (URISyntaxException ex) {
             Exceptions.printStackTrace(ex);
-            return guessWorkdir();
         }
+        if (wd == null) {
+            wd = guessWorkdir();
+            if (wd != null) {
+                setWorkingDirectory(repository.getUrl(), wd);
     }
-
-    @Override
-    public void propertyChange(PropertyChangeEvent evt) {
-        final List<Project> newProjects = 
getNewProjects((Project[])evt.getOldValue(), (Project[])evt.getNewValue());
-        rp.post(new Runnable() {
-            public void run() {
-                addToRecentProjects(newProjects, true);
             }
-        });
-    }
-
-    void remove(NbProjectHandleImpl aThis) {
-        recent.remove(aThis);
-        storeRecent();
-        projectHandle.firePropertyChange(ProjectHandle.PROP_SOURCE_LIST, 
null, null);
+        return wd;
     }
 
     void refresh() {
@@ -175,83 +161,86 @@
         prefs.put(WORKINGDIR + url, Utilities.toURI(dest).toString()); 
//NOI18N
     }
 
-    private synchronized void addToRecentProjects(List<Project> newProjects, 
boolean fireChanges) {
-        for (Project prj : newProjects) {
-            try {
-                if (isUnder(prj.getProjectDirectory())) {
-                    NbProjectHandleImpl nbHandle = 
RecentProjectsCache.getDefault().getProjectHandle(prj, this, removeHandler);
-                    recent.remove(nbHandle);
-                    recent.add(0, nbHandle);
-                    if (recent.size()>MAX_PROJECTS) {
-                        recent.remove(MAX_PROJECTS);
+    private synchronized boolean addToRecent(IDEProject... projects) {
+        boolean changed = false;
+        for (IDEProject ideProject : projects) {
+            boolean alreadyPresent = recent.remove(ideProject);
+            if (alreadyPresent || isUnder(ideProject)) {
+                recent.add(0, ideProject);
+                if (!alreadyPresent) {
+                    ideProject.addDeleteListener(projectListener);
                     }
+                changed = true;
+            }
+        }
+        while (recent.size() > MAX_PROJECTS) {
+            IDEProject ideProject = recent.remove(MAX_PROJECTS);
+            ideProject.removeDeleteListener(projectListener);
+            changed = true;
+        }
+        if (changed) {
                     storeRecent();
-                    if (fireChanges) {
-                        
projectHandle.firePropertyChange(ProjectHandle.PROP_SOURCE_LIST, null, null);
                     }    
-                }
-            } catch (IOException ex) {
-                
Logger.getLogger(SourceHandleImpl.class.getName()).fine("Project not found 
for " + prj);
-            }
-        }
+        return changed;
     }
 
-    private List<Project> getNewProjects(Project[] old, Project[] newp) {
-        if (newp == null) {
-            return Collections.emptyList();
-        } else if (old == null) {
-            return Arrays.asList(newp);
+    private synchronized boolean removeFromRecent(IDEProject ideProject) {
+        boolean removed = recent.remove(ideProject);
+        if (removed) {
+            ideProject.removeDeleteListener(projectListener);
+            storeRecent();
         }
-        List result = new ArrayList();
-        result.addAll(Arrays.asList(newp));
-        result.removeAll(Arrays.asList(old));
-        return result;
+        return removed;
     }
 
     private File guessWorkdir() {
-        if (recent.isEmpty()) {
+        URL url = null;
+        synchronized(this) {
+            if (!recent.isEmpty()) {
+                url = recent.get(0).getURL();
+            }
+        }
+        if (url != null) {
+            FileObject projectDirectory = URLMapper.findFileObject(url);
+            if (projectDirectory != null) {
+                FileObject parent = projectDirectory.getParent();
+                if (parent != null && parent.isValid()) {
+                    return FileUtil.toFile(parent);
+                }
+            }
+        }
             return null;
         }
-        try {
-            final FileObject parent = ((NbProjectHandleImpl) 
recent.iterator().next()).getProject().getProjectDirectory().getParent();
-            if (parent.isValid())
-                return FileUtil.toFile(parent);
-            return null;
-        } catch (Throwable t) {
-            return null;
-        }
-    }
 
     private void initRecent() {
-        if (prefs==null) {
-            //external repository not supported
+        if (prefs == null) { // external repository not supported
             return;
         }
+
+        ProjectServices projects = 
Lookup.getDefault().lookup(ProjectServices.class);
+        if (projects == null) {
+            return;
+        }
+
         List<String> roots = getStringList(prefs, RECENTPROJECTS_PREFIX + 
repository.getUrl());
         for (String root:roots) {
             try {
-                NbProjectHandleImpl nbH = 
RecentProjectsCache.getDefault().getProjectHandle(new URL(root), this, 
removeHandler);
-                if (nbH!=null)
-                    recent.add(nbH);
+                IDEProject ideProject = projects.getIDEProject(new 
URL(root));
+                if (ideProject != null) {
+                    recent.add(ideProject); // 'recent' not yet available 
outside, does not have to by synchronized here
+                    ideProject.addDeleteListener(projectListener);
+                }
             } catch (IOException ex) {
                 
Logger.getLogger(SourceHandleImpl.class.getName()).fine("Project not found 
for " + root);
             }
         }
-        int count = recent.size();
-        List list = new LinkedList();
-        final Project[] openProjects = 
OpenProjects.getDefault().getOpenProjects();
-        for (int i=0;count<MAX_PROJECTS && i<openProjects.length;i++) {
-            if (isUnder(openProjects[i].getProjectDirectory())) {
-                list.add(openProjects[i]);
-                count++;
-            }
+        projects.addProjectOpenListener(projectListener);
+        addToRecent(projects.getOpenProjects());
         }
         
-        addToRecentProjects(list, false);
-    }
-
-    private boolean isUnder(FileObject projectDirectory) {
-        String remoteLocation = (String) 
projectDirectory.getAttribute("ProvidedExtensions.RemoteLocation"); //NOI18N
+    private boolean isUnder(IDEProject ideProject) {
+        FileObject projectDirectory = 
URLMapper.findFileObject(ideProject.getURL());
+        String remoteLocation = projectDirectory != null ? 
VersioningQuery.getRemoteLocation(projectDirectory.toURI()) : null;
         if(remoteLocation == null) {
             return false;
         }
@@ -277,7 +266,7 @@
         return false;
     }
 
-    private boolean isUnder(String remoteLocation, String location) {
+    private static boolean isUnder(String remoteLocation, String location) {
         if (remoteLocation!=null && !remoteLocation.endsWith("/")) {//NOI18N
             remoteLocation+="/";//NOI18N
         }
@@ -299,14 +288,14 @@
     }
 
     private void storeRecent() {
+        if (prefs != null) {
         List<String> value = new ArrayList<String>();
-        for (NbProjectHandle nbp:recent) {
-            value.add(((NbProjectHandleImpl) nbp).getUrl());
+            for (IDEProject prj : recent) {
+                value.add(prj.getURL().toString());
         }
-        if (prefs!=null)
             putStringList(prefs, RECENTPROJECTS_PREFIX + 
repository.getUrl(), value);
     }
-
+    }
 
     /*
      * Helper method to get an array of Strings from preferences.
@@ -365,19 +354,38 @@
         }
     }
 
-    private NbProjectHandleImpl.RemoveHandler removeHandler = new 
NbProjectHandleImpl.RemoveHandler() {
-        @Override
-        public void remove(NbProjectHandleImpl nbProjectHandle) {
-            SourceHandleImpl.this.remove(nbProjectHandle);
-        }
-    };    
-
-    private File getWorkDir (String uriString) throws 
IllegalArgumentException, URISyntaxException {
+    private static File getWorkDir (String uriString) throws 
IllegalArgumentException, URISyntaxException {
         URI uri = new URI(uriString);
         final File file = Utilities.toFile(uri);
+        if (file == null || !file.exists()) {
+            return null;
+        }
         FileObject f = FileUtil.toFileObject(file);
         if (f==null || !f.isValid())
             return null;
         return file;
     }
+
+    private class IDEProjectListener implements IDEProject.OpenListener, 
IDEProject.DeleteListener {
+        private RequestProcessor rp = new 
RequestProcessor(SourceHandleImpl.class);
+
+        @Override
+        public void projectsOpened(final IDEProject[] projects) {
+            rp.post(new Runnable() { // in RP because of bug 179082
+                @Override
+                public void run() {
+                    if (addToRecent(projects)) {
+                        refresh();
 }
+                }
+            });
+        }
+
+        @Override
+        public void projectDeleted(IDEProject prj) {
+            if (removeFromRecent(prj)) {
+                refresh();
+            }
+        }
+    }
+}
diff --git a/projectui/nbproject/project.properties 
b/projectui/nbproject/project.properties
--- a/projectui/nbproject/project.properties
+++ b/projectui/nbproject/project.properties
@@ -42,7 +42,7 @@
 
 javac.compilerargs=-Xlint:unchecked
 javac.source=1.6
-spec.version.base=1.46.0
+spec.version.base=1.47.0
 
 javadoc.arch=${basedir}/arch.xml
 javadoc.apichanges=${basedir}/apichanges.xml
diff --git a/projectui/nbproject/project.xml b/projectui/nbproject/project.xml
--- a/projectui/nbproject/project.xml
+++ b/projectui/nbproject/project.xml
@@ -283,8 +283,6 @@
             <friend-packages>
                 <friend>com.microchip.mplab.nbide.welcome</friend>
                 <friend>com.sun.tools.swdev.sunstudio</friend>
-                <friend>org.netbeans.modules.kenai.ui</friend>
-                <friend>org.netbeans.modules.team.ui</friend>
                 <friend>org.netbeans.modules.welcome</friend>
                 <package>org.netbeans.modules.project.ui.api</package>
                 <package>org.netbeans.modules.project.ui.spi</package>
diff --git a/team.ui.util/manifest.mf b/team.ui.util/manifest.mf
--- a/team.ui.util/manifest.mf
+++ b/team.ui.util/manifest.mf
@@ -2,5 +2,4 @@
 AutoUpdate-Show-In-Client: false
 OpenIDE-Module: org.netbeans.modules.team.ui.util
 OpenIDE-Module-Localizing-Bundle: 
org/netbeans/modules/team/ui/util/Bundle.properties
-OpenIDE-Module-Specification-Version: 1.6
-
+OpenIDE-Module-Specification-Version: 1.7
diff --git a/team.ui.util/nbproject/project.xml 
b/team.ui.util/nbproject/project.xml
--- a/team.ui.util/nbproject/project.xml
+++ b/team.ui.util/nbproject/project.xml
@@ -67,6 +67,7 @@
                 <friend>org.netbeans.modules.bugtracking</friend>
                 <friend>org.netbeans.modules.kenai.ui</friend>
                 <friend>org.netbeans.modules.odcs.ui</friend>
+                <friend>org.netbeans.modules.odcs.versioning</friend>
                 <friend>org.netbeans.modules.team.ui</friend>
                 <friend>org.netbeans.modules.bugtracking.bridge</friend>
                 <package>org.netbeans.modules.team.ui.util.treelist</package>
diff --git 
a/team.ui.util/src/org/netbeans/modules/team/ide/spi/IDEProject.java 
b/team.ui.util/src/org/netbeans/modules/team/ide/spi/IDEProject.java
new file mode 100644
--- /dev/null
+++ b/team.ui.util/src/org/netbeans/modules/team/ide/spi/IDEProject.java
@@ -0,0 +1,143 @@
+/*
+ * 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.team.ide.spi;
+
+import java.net.URL;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+import javax.swing.Icon;
+
+/**
+ * Representation of a standalone (top-level) project the user can open in 
the
+ * IDE directly. It is used for visualization of projects the user opened or 
can
+ * open from the versioned sources obtained from a team server project. <p>
+ * Specific subclass should override addDeleteListener and implement the
+ * actual listening on project deletion.
+ *
+ * @author Tomas Pavek
+ */
+public abstract class IDEProject {
+    private String displayName;
+    private Icon icon;
+    private URL url;
+
+    private List<DeleteListener> deleteListeners = new 
CopyOnWriteArrayList();
+
+    protected IDEProject(String displayName, Icon icon, URL url) {
+        this.displayName = displayName;
+        this.icon = icon;
+        this.url = url;
+    }
+
+    public String getDisplayName() {
+        return displayName;
+    }
+
+    public Icon getIcon() {
+        return icon;
+    }
+
+    public URL getURL() {
+        return url;
+    }
+
+    /**
+     * To be overridden in subclass to start observing the actual project 
deletion.
+     * It should call notifyDeleted when the project is deleted.
+     * @param l
+     * @return true if listener was added (not existed already)
+     */
+    public synchronized boolean addDeleteListener(DeleteListener l) {
+        if (deleteListeners.contains(l)) {
+            return false;
+        } else {
+            deleteListeners.add(l);
+            return true;
+        }
+    }
+
+    public boolean removeDeleteListener(DeleteListener l) {
+        return deleteListeners.remove(l);
+    }
+
+    protected final List<DeleteListener> getDeleteListeners() {
+        return deleteListeners;
+    }
+
+    public final void notifyDeleted() {
+        for (DeleteListener dl : deleteListeners) {
+            dl.projectDeleted(this);
+        }
+    }
+
+    public interface OpenListener {
+        void projectsOpened(IDEProject[] prj);
+    }
+
+    public interface DeleteListener {
+        void projectDeleted(IDEProject prj);
+    }
+
+    // -----
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final IDEProject other = (IDEProject) obj;
+        if (this.url != other.url && (this.url == null || 
!this.url.equals(other.url))) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = 3;
+        hash = 67 * hash + (this.url != null ? this.url.hashCode() : 0);
+        return hash;
+    }
+}
diff --git 
a/team.ui.util/src/org/netbeans/modules/team/ide/spi/IDEServices.java 
b/team.ui.util/src/org/netbeans/modules/team/ide/spi/IDEServices.java
--- a/team.ui.util/src/org/netbeans/modules/team/ide/spi/IDEServices.java
+++ b/team.ui.util/src/org/netbeans/modules/team/ide/spi/IDEServices.java
@@ -151,16 +151,6 @@
     public boolean providesOpenHistory();
 
     /**
-     * Creates an animated busy icon (used e.g. in ProgressLabel) to be 
shown in
-     * UI (like the treelist nodes) that perform some operation (e.g. 
searching).
-     * May return null.
-     * 
-     * @return <code>BusyIcon</code> implementation of an animated busy 
icon, or
-     *         null if no specific implementation is available
-     */
-    public BusyIcon createBusyIcon();
-
-    /**
      * Meant to open a VCS history view where:
      * - it is possible to traverse the given resource history entries 
      * - a diff view is provided, showing the selected revision compared 
against 
@@ -176,6 +166,29 @@
     public boolean openHistory(String resourcePath, int line);
     
     /**
+     * Creates an animated busy icon (used e.g. in ProgressLabel) to be 
shown in
+     * UI (like the treelist nodes) that perform some operation (e.g. 
searching).
+     * May return null.
+     * 
+     * @return <code>BusyIcon</code> implementation of an animated busy 
icon, or
+     *         null if no specific implementation is available
+     */
+    public BusyIcon createBusyIcon();
+
+    /**
+     * Determines whether the capability of opening a directory in a file 
browse
+     * UI (e.g. Favorites window in NetBeans) is available.
+     * @return true if can open a directory in a Favorites UI
+     */
+    public boolean canOpenInFavorites();
+
+    /**
+     * Opens given directory in file browser (Favorites).
+     * @param workingDir 
+     */
+    public void openInFavorites(File workingDir);
+
+    /**
      * Provides access to a downloadable plugin - e.g. from the NetBeans UC
      */
     public interface Plugin {
@@ -197,7 +210,6 @@
      * Implementation can use a specific library, e.g. SwingX.
      */
     public interface BusyIcon extends Icon {
-
         /**
          * Called by timer (run by ProgressLabel) for next animation step.
          */
diff --git 
a/team.ui.util/src/org/netbeans/modules/team/ide/spi/ProjectServices.java 
b/team.ui.util/src/org/netbeans/modules/team/ide/spi/ProjectServices.java
--- a/team.ui.util/src/org/netbeans/modules/team/ide/spi/ProjectServices.java
+++ b/team.ui.util/src/org/netbeans/modules/team/ide/spi/ProjectServices.java
@@ -42,6 +42,8 @@
 
 package org.netbeans.modules.team.ide.spi;
 
+import java.io.File;
+import java.net.URL;
 import java.util.concurrent.Callable;
 import org.openide.filesystems.FileObject;
 import org.openide.util.Lookup;
@@ -90,5 +92,44 @@
     // BOS.getOpenFileObject();
     // FileObject getFileForCurrentSelection();  
     
+    /**
+     * Opens project of given URL in the IDE.
+     * @param url URL representing the project
+     * @return true if the project opened (false e.g. if not found)
+     */
+    public boolean openProject(URL url);
+
+    /**
+     * Lets the user open a project from within given working directory.
+     * @param workingDir 
+     */
+    public void openOtherProject(File workingDir);
+
+    /**
+     * Creates IDEProject representation for given URL.
+     * @param url URL representing the project
+     * @return IDEProject for given project URL, or null if the project does 
not exist
+     */
+    public IDEProject getIDEProject(URL url);
+
+    /**
+     * Provides information about all projects currently opened in the IDE
+     * (i.e. shown in a list of opened projects).
+     * @return IDEProject array representing all opened user projects
+     */
+    public IDEProject[] getOpenProjects();
+
+    /**
+     * Adds a listener to be informed about opening new projects. The 
listener
+     * should be held weakly in the implementation.
+     * @param listener 
+     */
+    public void addProjectOpenListener(IDEProject.OpenListener listener);
+
+    /**
+     * Removes listener on project opening.
+     * @param listener 
+     */
+    public void removeProjectOpenListener(IDEProject.OpenListener listener);
     
 }
diff --git a/team.ui/manifest.mf b/team.ui/manifest.mf
--- a/team.ui/manifest.mf
+++ b/team.ui/manifest.mf
@@ -3,4 +3,4 @@
 OpenIDE-Module-Localizing-Bundle: 
org/netbeans/modules/team/ui/Bundle.properties
 OpenIDE-Module-Layer: org/netbeans/modules/team/ui/resources/layer.xml
 OpenIDE-Module-Install: 
org/netbeans/modules/team/ui/ModuleLifecycleManager.class
-OpenIDE-Module-Specification-Version: 1.11
+OpenIDE-Module-Specification-Version: 1.12
diff --git a/team.ui/nbproject/project.xml b/team.ui/nbproject/project.xml
--- a/team.ui/nbproject/project.xml
+++ b/team.ui/nbproject/project.xml
@@ -42,23 +42,6 @@
                     </run-dependency>
                 </dependency>
                 <dependency>
-                    
<code-name-base>org.netbeans.modules.projectui</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>1.36</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    
<code-name-base>org.netbeans.modules.projectuiapi</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <release-version>1</release-version>
-                        <specification-version>1.58</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
                     
<code-name-base>org.netbeans.modules.queries</code-name-base>
                     <build-prerequisite/>
                     <compile-dependency/>
@@ -72,7 +55,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>1.6</specification-version>
+                        <specification-version>1.7</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
diff --git 
a/team.ui/src/org/netbeans/modules/team/ui/common/NbProjectHandleImpl.java 
b/team.ui/src/org/netbeans/modules/team/ui/common/NbProjectHandleImpl.java
deleted file mode 100644
--- a/team.ui/src/org/netbeans/modules/team/ui/common/NbProjectHandleImpl.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2010 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 2009 Sun Microsystems, Inc.
- */
-
-package org.netbeans.modules.team.ui.common;
-
-import java.io.IOException;
-import java.net.URL;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import javax.swing.Icon;
-import org.netbeans.api.project.Project;
-import org.netbeans.api.project.ProjectManager;
-import org.netbeans.api.project.ProjectUtils;
-import org.netbeans.modules.team.ui.spi.NbProjectHandle;
-import org.netbeans.modules.project.ui.api.UnloadedProjectInformation;
-import org.netbeans.modules.team.ui.spi.SourceHandle;
-import org.openide.filesystems.FileChangeAdapter;
-import org.openide.filesystems.FileEvent;
-import org.openide.filesystems.FileObject;
-import org.openide.filesystems.FileStateInvalidException;
-import org.openide.filesystems.URLMapper;
-import org.openide.util.Exceptions;
-
-/**
- * Handle representing netbeans project in team dashboard
- * @author Jan Becicka
- */
-public class NbProjectHandleImpl extends NbProjectHandle {
-
-    private Icon icon;
-    private String displayName;
-    URL url;
-    private SourceHandle parent;
-    private RemoveHandler removeHandler;
-
-    NbProjectHandleImpl(Project p, SourceHandle parent, RemoveHandler 
removeHandler) throws IOException {
-        displayName = ProjectUtils.getInformation(p).getDisplayName();
-        icon = ProjectUtils.getInformation(p).getIcon();
-        url = p.getProjectDirectory().getURL();
-        this.removeHandler = removeHandler;
-        p.getProjectDirectory().addFileChangeListener(new 
FileChangeAdapter() {
-            @Override
-            public void fileDeleted(FileEvent fe) {
-                try {
-                    if (fe.getFile().getURL().equals(url)) {
-                        remove();
-                    }
-                } catch (FileStateInvalidException ex) {
-                    //ignore
-                }
-            }
-        });
-        this.parent = parent;
-        assert this.parent!=null;
-        assert displayName!=null;
-        assert icon!=null;
-        assert url!=null;
-    }
-
-    NbProjectHandleImpl(UnloadedProjectInformation i, SourceHandle parent, 
RemoveHandler removeHandler) {
-        displayName = i.getDisplayName();
-        icon = i.getIcon();
-        url = i.getURL();
-        this.removeHandler = removeHandler;
-        this.parent = parent;
-        assert this.parent!=null;
-        assert displayName!=null;
-        assert icon!=null;
-        assert url!=null;
-    }
-
-    @Override
-    public String getDisplayName() {
-        return displayName;
-    }
-
-    @Override
-    public Icon getIcon() {
-        return icon;
-    }
-
-    /**
-     * Getter fot NB Project
-     * @return
-     */
-    public Project getProject() {
-        try {
-            final FileObject fo = URLMapper.findFileObject(url);
-            if (fo==null) {
-                return null;
-            }
-            Project project = ProjectManager.getDefault().findProject(fo);
-            if (project==null)
-                
Logger.getLogger(NbProjectHandleImpl.class.getName()).severe("Cannot find 
project for " + fo.getPath()); // NOI18N
-            return project;
-        } catch (IOException ex) {
-            
Logger.getLogger(NbProjectHandleImpl.class.getName()).log(Level.INFO, 
ex.getMessage(), ex);
-            remove();
-        } catch (IllegalArgumentException ex) {
-            Exceptions.printStackTrace(ex);
-        }
-        return null;
-    }
-
-    public void remove() {
-        removeHandler.remove(this);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == null) {
-            return false;
-        }
-        if (getClass() != obj.getClass()) {
-            return false;
-        }
-        final NbProjectHandleImpl other = (NbProjectHandleImpl) obj;
-        if (this.url != other.url && (this.url == null || 
!this.url.equals(other.url))) {
-            return false;
-        }
-        return true;
-    }
-
-    @Override
-    public int hashCode() {
-        int hash = 3;
-        hash = 67 * hash + (this.url != null ? this.url.hashCode() : 0);
-        return hash;
-    }
-
-    @Override
-    public String getUrl() {
-        return url.toString();
-    }
-    
-    public interface RemoveHandler {
-        void remove(NbProjectHandleImpl impl);
-    }
-}
diff --git 
a/team.ui/src/org/netbeans/modules/team/ui/common/NbProjectNode.java 
b/team.ui/src/org/netbeans/modules/team/ui/common/NbProjectNode.java
--- a/team.ui/src/org/netbeans/modules/team/ui/common/NbProjectNode.java
+++ b/team.ui/src/org/netbeans/modules/team/ui/common/NbProjectNode.java
@@ -52,9 +52,8 @@
 import javax.swing.JComponent;
 import javax.swing.JLabel;
 import javax.swing.JPanel;
+import org.netbeans.modules.team.ide.spi.IDEProject;
 import org.netbeans.modules.team.ui.spi.DashboardProvider;
-import org.netbeans.modules.team.ui.spi.NbProjectHandle;
-import org.netbeans.modules.team.ui.spi.TeamServer;
 import org.netbeans.modules.team.ui.util.treelist.LeafNode;
 import org.netbeans.modules.team.ui.util.treelist.TreeListNode;
 
@@ -65,13 +64,13 @@
  */
 public class NbProjectNode<P> extends LeafNode {
 
-    private final NbProjectHandle prj;
+    private final IDEProject prj;
 
     private LinkButton btn;
     private JPanel panel;
     private final DashboardProvider<P> dashboard;
 
-    public NbProjectNode( NbProjectHandle prj, TreeListNode parent, 
DashboardProvider<P> dashboard ) {
+    public NbProjectNode(IDEProject prj, TreeListNode parent, 
DashboardProvider<P> dashboard) {
         super( parent );
         assert prj!=null;
         this.prj = prj;
diff --git 
a/team.ui/src/org/netbeans/modules/team/ui/common/RecentProjectsCache.java 
b/team.ui/src/org/netbeans/modules/team/ui/common/RecentProjectsCache.java
deleted file mode 100644
--- a/team.ui/src/org/netbeans/modules/team/ui/common/RecentProjectsCache.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2010 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 2009 Sun Microsystems, Inc.
- */
-
-package org.netbeans.modules.team.ui.common;
-
-import java.io.IOException;
-import java.net.URL;
-import org.netbeans.api.project.Project;
-import org.netbeans.api.project.ui.OpenProjects;
-import org.netbeans.modules.project.ui.api.RecentProjects;
-import org.netbeans.modules.project.ui.api.UnloadedProjectInformation;
-import org.netbeans.modules.team.ui.spi.SourceHandle;
-import org.openide.filesystems.FileStateInvalidException;
-
-/**
- *
- * @author Jan Becicka
- */
-public class RecentProjectsCache {
-
-    private static RecentProjectsCache instance;
-
-    public static synchronized RecentProjectsCache getDefault() {
-        if (instance==null) {
-            instance = new RecentProjectsCache();
-        }
-        return instance;
-    }
-
-    public synchronized NbProjectHandleImpl getProjectHandle(URL url, 
SourceHandle src, NbProjectHandleImpl.RemoveHandler handler) throws 
FileStateInvalidException, IOException {
-        for (Project p : OpenProjects.getDefault().getOpenProjects()) {
-            if (p.getProjectDirectory().getURL().equals(url)) {
-                return new NbProjectHandleImpl(p, src, handler);
-            }
-        }
-        for (UnloadedProjectInformation i : 
RecentProjects.getDefault().getRecentProjectInformation()) {
-            if (i.getURL().equals(url)) {
-                return new NbProjectHandleImpl(i, src, handler);
-            }
-
-        }
-        return null;
-    }
-
-    public synchronized NbProjectHandleImpl getProjectHandle(Project p, 
SourceHandle src, NbProjectHandleImpl.RemoveHandler handler) throws 
IOException  {
-        return new NbProjectHandleImpl(p, src, handler);
-    }
-
-}
diff --git 
a/team.ui/src/org/netbeans/modules/team/ui/common/SourceListNode.java 
b/team.ui/src/org/netbeans/modules/team/ui/common/SourceListNode.java
--- a/team.ui/src/org/netbeans/modules/team/ui/common/SourceListNode.java
+++ b/team.ui/src/org/netbeans/modules/team/ui/common/SourceListNode.java
@@ -45,12 +45,11 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import org.netbeans.modules.team.ide.spi.IDEProject;
 import org.netbeans.modules.team.ui.spi.DashboardProvider;
-import org.netbeans.modules.team.ui.spi.NbProjectHandle;
 import org.netbeans.modules.team.ui.spi.ProjectHandle;
 import org.netbeans.modules.team.ui.spi.SourceAccessor;
 import org.netbeans.modules.team.ui.spi.SourceHandle;
-import org.netbeans.modules.team.ui.spi.TeamServer;
 import org.netbeans.modules.team.ui.util.treelist.LeafNode;
 import org.netbeans.modules.team.ui.util.treelist.TreeListNode;
 import org.openide.util.NbBundle;
@@ -83,16 +82,18 @@
             res.addAll(getRecentProjectsNodes(s));
             if (s.getWorkingDirectory() != null) {
                 res.add(new OpenNbProjectNode(s, this, dashboard ));
+                if (dashboard.getSourceAccessor().getOpenFavoritesAction(s) 
!= null) {
                 res.add(new OpenFavoritesNode(s, this, dashboard ));
             }
         }
+        }
         return res;
     }
 
     private List<TreeListNode> getRecentProjectsNodes(SourceHandle handle) {
         ArrayList<TreeListNode> res = new ArrayList<TreeListNode>();
-        for( NbProjectHandle s : handle.getRecentProjects()) {
-            res.add( new NbProjectNode( s, this, dashboard ) );
+        for (IDEProject p : handle.getRecentProjects()) {
+            res.add(new NbProjectNode(p, this, dashboard));
         }
         return res;
     }
diff --git 
a/team.ui/src/org/netbeans/modules/team/ui/spi/NbProjectHandle.java 
b/team.ui/src/org/netbeans/modules/team/ui/spi/NbProjectHandle.java
deleted file mode 100644
--- a/team.ui/src/org/netbeans/modules/team/ui/spi/NbProjectHandle.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2010 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 2009 Sun Microsystems, Inc.
- */
-
-package org.netbeans.modules.team.ui.spi;
-
-import javax.swing.Icon;
-
-/**
- * Handle representing netbeans project
- * @author Jan Becicka
- */
-public abstract class NbProjectHandle {
-    /**
-     * DisplayName of given project
-     * @return
-     */
-    public abstract String getDisplayName();
-    /**
-     * Icon of given project
-     * @return
-     */
-    public abstract Icon getIcon();
-    /**
-     * Url of the given project
-     * @return
-     */    
-    public abstract String getUrl();
-}
diff --git a/team.ui/src/org/netbeans/modules/team/ui/spi/SourceAccessor.java 
b/team.ui/src/org/netbeans/modules/team/ui/spi/SourceAccessor.java
--- a/team.ui/src/org/netbeans/modules/team/ui/spi/SourceAccessor.java
+++ b/team.ui/src/org/netbeans/modules/team/ui/spi/SourceAccessor.java
@@ -7,11 +7,12 @@
 
 import java.util.List;
 import javax.swing.Action;
+import org.netbeans.modules.team.ide.spi.IDEProject;
 
 /**
  * Main access point to Teams's source versioning API.
  * All methods except those returning an Action or ActionListener are allowed
- * to block indefinetely as they will be called outside AWT thread.
+ * to block indefinitely as they will be called outside AWT thread.
  * However the Dashboard UI may declare appropriate service(s) as unreachable
  * after some configurable time out interval.
  * 
@@ -24,7 +25,9 @@
     /**
      * 
      * @param src
-     * @return 
+     * @return Action that opens the working directory of given SourceHandle
+     *         in a file browser UI (like Favorites window), or null if such
+     *         capability does not exist.
      */
     public abstract Action getOpenFavoritesAction(SourceHandle src);
 
@@ -55,7 +58,7 @@
      * @param prj
      * @return default action on Project
      */
-    public abstract Action getDefaultAction( NbProjectHandle prj );
+    public abstract Action getDefaultAction(IDEProject prj);
 
     /**
      * Default action for "other" link
diff --git a/team.ui/src/org/netbeans/modules/team/ui/spi/SourceHandle.java 
b/team.ui/src/org/netbeans/modules/team/ui/spi/SourceHandle.java
--- a/team.ui/src/org/netbeans/modules/team/ui/spi/SourceHandle.java
+++ b/team.ui/src/org/netbeans/modules/team/ui/spi/SourceHandle.java
@@ -6,7 +6,7 @@
 package org.netbeans.modules.team.ui.spi;
 
 import java.io.File;
-import java.util.List;
+import org.netbeans.modules.team.ide.spi.IDEProject;
 
 /**
  * Abstraction for a single source repository (a line in 'Sources' section).
@@ -35,7 +35,7 @@
      * String featureName = source.getScmFeatureName();
      * if (featureName.equals(KenaiService.Names.SUBVERSION)) { ... }
      * </pre>
-     * @return the name of the issue tracking fature
+     * @return the name of the issue tracking feature
      */
     public abstract String getScmFeatureName();
 
@@ -43,7 +43,7 @@
      * getter for max 5 recent projects
      * @return
      */
-    public abstract List<NbProjectHandle> getRecentProjects();
+    public abstract Iterable<IDEProject> getRecentProjects();
 
     /**
      * getter for last checked out working directory

[hg] main-silver: reducing team direct dependencies on project U...

Tomas Pavek 06/21/2013

Project Features

About this Project

ConnectedDeveloper was started in November 2009, is owned by tpavek, and has 64 members.
By use of this website, you agree to the NetBeans Policies and Terms of Use (revision 20131025.e7cbc9d). © 2013, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo
 
 
Close
loading
Please Confirm
Close