/** @return All the currently checked projects in the projectsList tree */
  public Set<ProjectRecord> getCheckedProjects() {
    HashSet<ProjectRecord> ret = new HashSet<ProjectRecord>();
    for (Object selected : projectsList.getCheckedElements()) ret.add((ProjectRecord) selected);

    return ret;
  }
  /**
   * Update the list of projects based on path. This will not check any projects.
   *
   * @param path
   */
  void setProjectsList(final String path) {
    // on an empty path empty selectedProjects
    if (path == null || path.length() == 0) {
      selectedProjects = new ProjectRecord[0];
      projectsList.refresh(true);
      checkPageComplete();
      lastPath = path;
      setErrorMessage(UIText.GitProjectsImportPage_NoProjectsMessage);
      return;
    }

    final File directory = new File(path);
    long modified = directory.lastModified();
    if (path.equals(lastPath) && lastModified == modified) {
      // since the file/folder was not modified and the path did not
      // change, no refreshing is required
      return;
    }

    setErrorMessage(null);

    lastPath = path;
    lastModified = modified;

    try {
      getContainer()
          .run(
              true,
              true,
              new IRunnableWithProgress() {

                public void run(IProgressMonitor monitor) {

                  monitor.beginTask(UIText.WizardProjectsImportPage_SearchingMessage, 100);
                  selectedProjects = new ProjectRecord[0];
                  Collection<File> files = new ArrayList<File>();
                  monitor.worked(10);
                  if (directory.isDirectory()) {

                    if (!collectProjectFilesFromDirectory(files, directory, null, monitor)) {
                      return;
                    }
                    Iterator<File> filesIterator = files.iterator();
                    selectedProjects = new ProjectRecord[files.size()];
                    int index = 0;
                    monitor.worked(50);
                    monitor.subTask(UIText.WizardProjectsImportPage_ProcessingMessage);
                    while (filesIterator.hasNext()) {
                      File file = filesIterator.next();
                      selectedProjects[index] = new ProjectRecord(file);
                      index++;
                    }

                    if (files.isEmpty())
                      // run in UI thread
                      Display.getDefault()
                          .syncExec(
                              new Runnable() {
                                public void run() {
                                  setErrorMessage(UIText.GitProjectsImportPage_NoProjectsMessage);
                                }
                              });
                  } else {
                    monitor.worked(60);
                  }
                  monitor.done();
                }
              });
    } catch (InvocationTargetException e) {
      Activator.logError(e.getMessage(), e);
    } catch (InterruptedException e) {
      // Nothing to do if the user interrupts.
    }

    projectsList.refresh(true);
    if (getValidProjects().length < selectedProjects.length) {
      setMessage(UIText.WizardProjectsImportPage_projectsInWorkspace, WARNING);
    } else {
      setMessage(UIText.WizardProjectsImportPage_ImportProjectsDescription);
    }
    enableSelectAllButtons();
    checkPageComplete();
  }
 private void enableSelectAllButtons() {
   int itemCount = getValidProjects().length;
   int selectionCount = projectsList.getCheckedLeafCount();
   selectAll.setEnabled(itemCount > selectionCount && itemCount > 0);
   deselectAll.setEnabled(selectionCount > 0);
 }
  /**
   * Create the checkbox list for the found projects.
   *
   * @param workArea
   */
  private void createProjectsList(Composite workArea) {
    Label title = new Label(workArea, SWT.NONE);
    title.setText(UIText.WizardProjectsImportPage_ProjectsListTitle);

    Composite listComposite = new Composite(workArea, SWT.NONE);
    GridLayout layout = new GridLayout();
    layout.numColumns = 2;
    layout.marginWidth = 0;
    layout.makeColumnsEqualWidth = false;
    listComposite.setLayout(layout);

    listComposite.setLayoutData(
        new GridData(GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL | GridData.FILL_BOTH));

    PatternFilter filter =
        new PatternFilter() {

          @Override
          public boolean isElementVisible(Viewer viewer, Object element) {

            if (getCheckedProjects().contains(element)) return true;

            return super.isElementVisible(viewer, element);
          }
        };

    FilteredCheckboxTree filteredTree =
        new FilteredCheckboxTree(listComposite, null, SWT.NONE, filter);

    filteredTree.setInitialText(UIText.WizardProjectsImportPage_filterText);
    projectsList = filteredTree.getCheckboxTreeViewer();
    GridData listData =
        new GridData(GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL | GridData.FILL_BOTH);
    projectsList.getControl().setLayoutData(listData);
    projectsList.addCheckStateListener(
        new ICheckStateListener() {

          public void checkStateChanged(CheckStateChangedEvent event) {
            ProjectRecord element = (ProjectRecord) event.getElement();
            if (isProjectInWorkspace(element.getProjectName())) {
              projectsList.setChecked(element, false);
            }
            enableSelectAllButtons();
          }
        });

    // a bug in the CachedCheckboxTreeView requires us to not return null
    final Object[] children = new Object[0];

    projectsList.setContentProvider(
        new ITreeContentProvider() {

          public Object[] getChildren(Object parentElement) {
            return children;
          }

          public Object[] getElements(Object inputElement) {
            return selectedProjects;
          }

          public boolean hasChildren(Object element) {
            return false;
          }

          public Object getParent(Object element) {
            return null;
          }

          public void dispose() {
            // ignore
          }

          public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
            // ignore
          }
        });

    projectsList
        .getTree()
        .addSelectionListener(
            new SelectionAdapter() {
              public void widgetSelected(SelectionEvent e) {
                checkPageComplete();
              }
            });

    projectsList.setLabelProvider(new ProjectLabelProvider());

    projectsList.setInput(this);
    projectsList.setComparator(new ViewerComparator());
    createSelectionButtons(listComposite);
  }