@SuppressWarnings("rawtypes")
  public static CheckedTreeSelectionDialog createMulti(
      Shell parent,
      String title,
      String message,
      Class[] filter,
      Object input,
      List selectedElements) {
    CheckedTreeSelectionDialog diag =
        new CheckedTreeSelectionDialog(
            parent, new WorkbenchLabelProvider(), new BaseWorkbenchContentProvider());

    configure(diag, title, message);

    if (filter.length > 0) {
      diag.addFilter(new TypedViewerFilter(filter));
    }

    diag.setInput(input);

    if (selectedElements != null) {
      diag.setInitialElementSelections(selectedElements);
    }
    return diag;
  }
  /**
   * Creates and opens a dialog enabling the user to select one or more elements from the specified
   * input tree.
   *
   * @param shell The parent shell for the dialog.
   * @param input The input for the dialog's tree.
   * @param allowMultipleSelections Whether or not to allow multiple items to be selected. If false,
   *     then only one item may be selected from the tree, otherwise the tree's selection will be
   *     determined by checkboxes.
   * @return The result of the dialog, usually either {@link Window#OK} or {@link Window#CANCEL}.
   */
  public int openDialog(Shell shell, Object input, boolean allowMultipleSelections) {

    // Create the dialog if necessary.
    final SelectionDialog dialog;

    // Set up the content and label providers. These are required for
    // any TreeViewer.
    ITreeContentProvider contentProvider = createContentProvider();
    ILabelProvider labelProvider = createLabelProvider();

    // Create a dialog with or without checkboxes in the tree.
    if (allowMultipleSelections) {
      dialog = createCheckedTreeSelectionDialog(shell, labelProvider, contentProvider);
    } else {
      dialog = createElementTreeSelectionDialog(shell, labelProvider, contentProvider);
    }

    // Set its title and message.
    dialog.setTitle(title);
    dialog.setMessage(message);

    setInput(input);

    // Set the input and refresh the viewer.
    if (allowMultipleSelections) {
      CheckedTreeSelectionDialog treeDialog = (CheckedTreeSelectionDialog) dialog;
      treeDialog.setInput(root);
      if (!initialSelection.isEmpty()) {
        treeDialog.setInitialSelections(initialSelection.toArray());
        newSelection.addAll(initialSelection);
      }
    } else {
      ElementTreeSelectionDialog treeDialog = (ElementTreeSelectionDialog) dialog;
      treeDialog.setInput(root);
      if (!initialSelection.isEmpty()) {
        Node initialNode = initialSelection.iterator().next();
        treeDialog.setInitialSelection(initialNode);
        newSelection.add(initialNode);
      }
    }

    // Return the result of opening the dialog.
    int result = dialog.open();

    // If the dialog was closed or cancelled, reset the selection to the
    // initial one.
    if (result != Window.OK) {
      newSelection.clear();
      for (Node node : initialSelection) {
        newSelection.add(node);
      }
    }

    return result;
  }
  protected void handleScanButtonPressed() {
    ScannedFilesContentProvider contentProvider =
        new ScannedFilesContentProvider(suffixesText.getText());
    CheckedTreeSelectionDialog dialog =
        new CheckedTreeSelectionDialog(
            SpringUIUtils.getStandardDisplay().getActiveShell(),
            new ScannedFilesLabelProvider(),
            contentProvider) {

          @Override
          protected Control createDialogArea(Composite parent) {
            Composite composite = (Composite) super.createDialogArea(parent);
            Label note = new Label(composite, SWT.WRAP);
            note.setText(BeansUIPlugin.getResourceString(SCAN_NOTE_LABEL));
            note.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
            return composite;
          }
        };
    dialog.setTitle(BeansUIPlugin.getResourceString(DIALOG_TITLE));
    dialog.setMessage(BeansUIPlugin.getResourceString(DIALOG_MESSAGE));
    dialog.addFilter(new ConfigFileFilter(project.getConfigSuffixes()));
    dialog.setValidator(new StorageSelectionValidator(true));
    dialog.setInput(project.getProject());
    dialog.setSorter(new JavaElementSorter());
    dialog.setInitialSelections(contentProvider.getElements(project.getProject()));

    if (dialog.open() == Window.OK) {
      Object[] selection = dialog.getResult();
      if (selection != null && selection.length > 0) {
        for (Object element : selection) {
          String config;
          if (element instanceof ZipEntryStorage) {
            ZipEntryStorage storage = (ZipEntryStorage) element;
            config = storage.getFullName();
          } else {
            IFile file = (IFile) element;
            config = file.getProjectRelativePath().toString();
          }
          project.addConfig(config, IBeansConfig.Type.MANUAL);
        }
        configsViewer.refresh(false);
        hasUserMadeChanges = true;
      }
    }
  }
  /**
   * Creates a dialog used to select <i>multiple</i> values from the input tree.
   *
   * @param shell The parent shell for the dialog.
   * @param labelProvider The label provider for the tree.
   * @param contentProvider The content provider for the tree.
   * @return The new dialog.
   */
  private CheckedTreeSelectionDialog createCheckedTreeSelectionDialog(
      Shell shell, ILabelProvider labelProvider, ITreeContentProvider contentProvider) {

    // Create a custom check-state listener to update the selected elements
    // on the fly.
    final ICheckStateListener checkStateListener = createCheckStateListener();

    CheckedTreeSelectionDialog treeDialog =
        new CheckedTreeSelectionDialog(shell, labelProvider, contentProvider) {
          /*
           * (non-Javadoc)
           * @see org.eclipse.ui.dialogs.CheckedTreeSelectionDialog#createSelectionButtons(org.eclipse.swt.widgets.Composite)
           */
          @Override
          protected Composite createSelectionButtons(Composite composite) {
            Composite buttonComposite = super.createSelectionButtons(composite);

            // Add listeners to the select-all and deselect-all buttons
            // because they do not trigger the check-state listener.
            getButton(IDialogConstants.SELECT_ALL_ID)
                .addSelectionListener(
                    new SelectionAdapter() {
                      @Override
                      public void widgetSelected(SelectionEvent e) {
                        newSelection.clear();
                        checkNode(root, true);
                      }
                    });
            getButton(IDialogConstants.DESELECT_ALL_ID)
                .addSelectionListener(
                    new SelectionAdapter() {
                      @Override
                      public void widgetSelected(SelectionEvent e) {
                        newSelection.clear();
                      }
                    });

            return buttonComposite;
          }

          /*
           * (non-Javadoc)
           * @see org.eclipse.ui.dialogs.CheckedTreeSelectionDialog#createTreeViewer(org.eclipse.swt.widgets.Composite)
           */
          @Override
          protected CheckboxTreeViewer createTreeViewer(Composite parent) {
            // Create the default TreeViewer.
            CheckboxTreeViewer viewer = super.createTreeViewer(parent);

            // Add the check state provider and listener.
            viewer.addCheckStateListener(checkStateListener);

            return viewer;
          }
        };

    // Set this flag so the "grayed" state of parent nodes is handled
    // properly.
    treeDialog.setContainerMode(true);

    return treeDialog;
  }