/**
   * Tests identification of source bundles in a 3.0.2 install.
   *
   * @throws Exception
   */
  public void testClassicSourcePlugins() throws Exception {
    // extract the 3.0.2 skeleton
    IPath location = extractClassicPlugins();

    // the new way
    ITargetDefinition definition = getNewTarget();
    ITargetLocation container = getTargetService().newDirectoryLocation(location.toOSString());
    definition.setTargetLocations(new ITargetLocation[] {container});

    definition.resolve(null);
    TargetBundle[] bundles = definition.getBundles();
    List source = new ArrayList();
    for (int i = 0; i < bundles.length; i++) {
      TargetBundle sb = bundles[i];
      if (sb.isSourceBundle()) {
        source.add(sb);
      }
    }

    assertEquals("Wrong number of source bundles", 4, source.size());
    Set names = new HashSet();
    for (int i = 0; i < source.size(); i++) {
      names.add(((TargetBundle) source.get(i)).getBundleInfo().getSymbolicName());
    }
    String[] expected =
        new String[] {
          "org.eclipse.platform.source",
          "org.eclipse.jdt.source",
          "org.eclipse.pde.source",
          "org.eclipse.platform.source.win32.win32.x86"
        };
    for (int i = 0; i < expected.length; i++) {
      assertTrue("Missing source for " + expected[i], names.contains(expected[i]));
    }
  }
  /**
   * Tests that resetting the target platform should work OK (i.e. is equivalent to the models in
   * the default target platform).
   *
   * @throws CoreException
   */
  public void testResetTargetPlatform() throws Exception {
    ITargetDefinition definition = getDefaultTargetPlatorm();
    Set urls = getAllBundleURLs(definition);
    Set fragments = new HashSet();
    TargetBundle[] bundles = definition.getBundles();
    for (int i = 0; i < bundles.length; i++) {
      if (bundles[i].isFragment()) {
        fragments.add(new File(bundles[i].getBundleInfo().getLocation()).toURL());
      }
    }

    // current platform
    IPluginModelBase[] models = TargetPlatformHelper.getPDEState().getTargetModels();

    // should be equivalent
    assertEquals("Should have same number of bundles", urls.size(), models.length);
    for (int i = 0; i < models.length; i++) {
      String location = models[i].getInstallLocation();
      URL url = new File(location).toURL();
      assertTrue("Missing plug-in " + location, urls.contains(url));
      if (models[i].isFragmentModel()) {
        assertTrue("Missing fragmnet", fragments.remove(url));
      }
    }
    assertTrue("Different number of fragments", fragments.isEmpty());
  }
  /**
   * Tests reading a 3.0.2 install with a mix of classic and OSGi plug-ins.
   *
   * @throws Exception
   */
  public void testClassicPlugins() throws Exception {
    // extract the 3.0.2 skeleton
    IPath location = extractClassicPlugins();

    // the new way
    ITargetDefinition definition = getNewTarget();
    ITargetLocation container = getTargetService().newDirectoryLocation(location.toOSString());
    definition.setTargetLocations(new ITargetLocation[] {container});
    Set urls = getAllBundleURLs(definition);
    assertTrue("Must be bundles", urls.size() > 0);

    Preferences store = PDECore.getDefault().getPluginPreferences();
    boolean restore = store.getBoolean(ICoreConstants.TARGET_PLATFORM_REALIZATION);
    try {
      store.setValue(ICoreConstants.TARGET_PLATFORM_REALIZATION, false);
      // the old way
      URL[] pluginPaths = PluginPathFinder.getPluginPaths(location.toOSString());
      for (int i = 0; i < pluginPaths.length; i++) {
        URL url = pluginPaths[i];
        if (!urls.contains(url)) {
          System.err.println(url.toString());
        }
      }
      assertEquals("Wrong number of bundles", pluginPaths.length, urls.size());
    } finally {
      store.setValue(ICoreConstants.TARGET_PLATFORM_REALIZATION, restore);
    }
  }
 /**
  * Retrieves all bundles (source and code) in the given target definition returning them as a set
  * of URLs.
  *
  * @param target target definition
  * @return all bundle URLs
  */
 protected Set getAllBundleURLs(ITargetDefinition target) throws Exception {
   if (!target.isResolved()) {
     target.resolve(null);
   }
   TargetBundle[] bundles = target.getBundles();
   Set urls = new HashSet(bundles.length);
   for (int i = 0; i < bundles.length; i++) {
     urls.add(new File(bundles[i].getBundleInfo().getLocation()).toURL());
   }
   return urls;
 }
  /**
   * Tests a JDT feature bundle container contains the appropriate bundles for a specific OS.
   *
   * @throws Exception
   */
  public void testMacOSFeatureBundleContainer() throws Exception {
    // extract the feature
    IPath location = extractModifiedFeatures();

    ITargetDefinition definition = getNewTarget();
    definition.setOS(Platform.OS_MACOSX);
    ITargetLocation container =
        getTargetService().newFeatureLocation(location.toOSString(), "org.eclipse.jdt", null);
    container.resolve(definition, null);
    TargetBundle[] bundles = container.getBundles();

    List expected = new ArrayList();
    expected.add("org.eclipse.jdt");
    expected.add("org.eclipse.jdt.launching");
    // 2 versions of JUnit
    expected.add("org.junit");
    expected.add("org.junit");
    expected.add("org.junit4");
    expected.add("org.eclipse.jdt.launching.macosx");

    assertEquals("Wrong number of bundles in JDT feature", expected.size(), bundles.length);
    for (int i = 0; i < bundles.length; i++) {
      String symbolicName = bundles[i].getBundleInfo().getSymbolicName();
      expected.remove(symbolicName);
      if (symbolicName.equals("org.eclipse.jdt.launching.macosx")) {
        // the bundle should be missing unless on Mac
        IStatus status = bundles[i].getStatus();
        if (Platform.getOS().equals(Platform.OS_MACOSX)) {
          assertTrue("Mac bundle should be present", status.isOK());
        } else {
          assertFalse("Mac bundle should be missing", status.isOK());
          assertEquals(
              "Mac bundle should be mssing",
              TargetBundle.STATUS_PLUGIN_DOES_NOT_EXIST,
              status.getCode());
        }
      }
    }
    Iterator iterator = expected.iterator();
    while (iterator.hasNext()) {
      String name = (String) iterator.next();
      System.err.println("Missing: " + name);
    }
    assertTrue("Wrong bundles in JDT feature", expected.isEmpty());

    // should be no source bundles
    for (int i = 0; i < bundles.length; i++) {
      TargetBundle bundle = bundles[i];
      assertFalse("Should be no source bundles", bundle.isSourceBundle());
    }
  }
  /**
   * Tests reading a 3.0 style plug-in that has a MANIFEST file that is not a bundle manifest.
   *
   * @throws Exception
   */
  public void testClassicPluginsWithNonBundleManifest() throws Exception {
    // extract the plug-in
    IPath location = extractClassicNonBundleManifestPlugins();

    // the new way
    ITargetDefinition definition = getNewTarget();
    ITargetLocation container = getTargetService().newDirectoryLocation(location.toOSString());
    definition.setTargetLocations(new ITargetLocation[] {container});
    definition.resolve(null);
    TargetBundle[] bundles = definition.getAllBundles();
    assertEquals("Wrong number of bundles", 1, bundles.length);
    assertEquals(
        "Wrong bundle", "org.eclipse.core.variables", bundles[0].getBundleInfo().getSymbolicName());
  }
  /**
   * Tests setting the target platform to the stored JDT feature test data
   *
   * @throws Exception
   */
  public void testSetTargetPlatformToJdtFeature() throws Exception {
    try {
      // extract the feature
      IPath location = extractModifiedFeatures();
      // org.eclipse.jdt_3.6.0.v20100105-0800-7z8VFR9FMTb52_pOyKHhoek1

      ITargetDefinition target = getNewTarget();
      ITargetLocation container =
          getTargetService()
              .newFeatureLocation(
                  location.toOSString(),
                  "org.eclipse.jdt",
                  "3.6.0.v20100105-0800-7z8VFR9FMTb52_pOyKHhoek1");

      target.setTargetLocations(new ITargetLocation[] {container});

      setTargetPlatform(target);

      List expected = new ArrayList();
      expected.add("org.eclipse.jdt");
      expected.add("org.eclipse.jdt.launching");
      // 2 versions of JUnit
      expected.add("org.junit");
      expected.add("org.junit");
      expected.add("org.junit4");
      if (Platform.getOS().equals(Platform.OS_MACOSX)) {
        expected.add("org.eclipse.jdt.launching.macosx");
      }

      // current platform
      IPluginModelBase[] models = TargetPlatformHelper.getPDEState().getTargetModels();

      assertEquals("Wrong number of bundles in JDT feature", expected.size(), models.length);
      for (int i = 0; i < models.length; i++) {
        expected.remove(models[i].getPluginBase().getId());
        assertTrue(models[i].isEnabled());
      }
      Iterator iterator = expected.iterator();
      while (iterator.hasNext()) {
        String name = (String) iterator.next();
        System.err.println("Missing: " + name);
      }
      assertTrue("Wrong bundles in target platform", expected.isEmpty());
    } finally {
      resetTargetPlatform();
    }
  }
  /**
   * Tests that a target definition equivalent to the default target platform contains the same
   * bundles as the default target platform using the platform's configuration location (which will
   * do target weaving). This is really only tested when run as a JUnit plug-in test suite from
   * within Eclipse.
   *
   * @throws Exception
   */
  public void testWovenTargetPlatform() throws Exception {
    // the new way
    ITargetDefinition definition = getNewTarget();
    ITargetLocation container =
        getTargetService()
            .newProfileLocation(
                TargetPlatform.getDefaultLocation(),
                new File(Platform.getConfigurationLocation().getURL().getFile()).getAbsolutePath());
    definition.setTargetLocations(new ITargetLocation[] {container});
    Set urls = getAllBundleURLs(definition);

    // the old way
    URL[] pluginPaths = PluginPathFinder.getPluginPaths(TargetPlatform.getDefaultLocation());
    assertEquals("Should have same number of bundles", pluginPaths.length, urls.size());
    for (int i = 0; i < pluginPaths.length; i++) {
      URL url = pluginPaths[i];
      assertTrue("Missing plug-in " + url.toString(), urls.contains(url));
    }
  }
  /**
   * Tests that a target definition based on the default target platform restricted to a subset of
   * bundle versions contains the right set.
   *
   * @throws Exception
   */
  public void testVersionRestrictedDefaultTargetPlatform() throws Exception {
    ITargetDefinition definition = getNewTarget();
    ITargetLocation container =
        getTargetService().newProfileLocation(TargetPlatform.getDefaultLocation(), null);
    definition.setTargetLocations(new ITargetLocation[] {container});
    List infos = getAllBundleInfos(definition);
    // find right versions
    String v1 = null;
    String v2 = null;
    Iterator iterator = infos.iterator();
    while (iterator.hasNext() && (v2 == null || v1 == null)) {
      BundleInfo info = (BundleInfo) iterator.next();
      if (info.getSymbolicName().equals("org.eclipse.jdt.launching")) {
        v1 = info.getVersion();
      } else if (info.getSymbolicName().equals("org.eclipse.jdt.debug")) {
        v2 = info.getVersion();
      }
    }
    assertNotNull(v1);
    assertFalse(v1.equals(BundleInfo.EMPTY_VERSION));
    assertNotNull(v2);
    assertFalse(v2.equals(BundleInfo.EMPTY_VERSION));

    NameVersionDescriptor[] restrictions =
        new NameVersionDescriptor[] {
          new NameVersionDescriptor("org.eclipse.jdt.launching", v1),
          new NameVersionDescriptor("org.eclipse.jdt.debug", v2)
        };
    definition.setIncluded(restrictions);
    infos = getAllBundleInfos(definition);

    assertEquals("Wrong number of bundles", 2, infos.size());
    iterator = infos.iterator();
    while (iterator.hasNext()) {
      BundleInfo info = (BundleInfo) iterator.next();
      if (info.getSymbolicName().equals("org.eclipse.jdt.launching")) {
        assertEquals(v1, info.getVersion());
      } else if (info.getSymbolicName().equals("org.eclipse.jdt.debug")) {
        assertEquals(v2, info.getVersion());
      }
    }
  }
  /**
   * Tests that a target definition equivalent to the default target platform contains the same
   * bundles as the default target platform (this is an explicit location with no target weaving),
   * when created with a variable referencing ${eclipse_home}
   *
   * @throws Exception
   */
  public void testEclipseHomeTargetPlatform() throws Exception {
    // the new way
    ITargetDefinition definition = getNewTarget();
    ITargetLocation container = getTargetService().newProfileLocation("${eclipse_home}", null);
    definition.setTargetLocations(new ITargetLocation[] {container});
    Set urls = getAllBundleURLs(definition);

    // the old way
    IPath location = new Path(TargetPlatform.getDefaultLocation());
    URL[] pluginPaths =
        P2Utils.readBundlesTxt(
            location.toOSString(), location.append("configuration").toFile().toURL());
    // pluginPaths will be null (and NPE) when self-hosting and the target platform is not a real
    // installation
    assertEquals("Should have same number of bundles", pluginPaths.length, urls.size());
    for (int i = 0; i < pluginPaths.length; i++) {
      URL url = pluginPaths[i];
      assertTrue("Missing plug-in " + url.toString(), urls.contains(url));
    }
  }
  /**
   * Tests that a target definition based on the default target platform restricted to a subset of
   * bundles contains the right set.
   *
   * @throws Exception
   */
  public void testRestrictedDefaultTargetPlatform() throws Exception {
    ITargetDefinition definition = getNewTarget();
    ITargetLocation container =
        getTargetService().newProfileLocation(TargetPlatform.getDefaultLocation(), null);
    NameVersionDescriptor[] restrictions =
        new NameVersionDescriptor[] {
          new NameVersionDescriptor("org.eclipse.jdt.launching", null),
          new NameVersionDescriptor("org.eclipse.jdt.debug", null)
        };
    definition.setTargetLocations(new ITargetLocation[] {container});
    definition.setIncluded(restrictions);
    List infos = getAllBundleInfos(definition);

    assertEquals("Wrong number of bundles", 2, infos.size());
    Set set = collectAllSymbolicNames(infos);
    for (int i = 0; i < restrictions.length; i++) {
      NameVersionDescriptor info = restrictions[i];
      set.remove(info.getId());
    }
    assertEquals("Wrong bundles", 0, set.size());
  }
  /**
   * Tests the ability to add arguments to a target platform and have them show up on new configs
   *
   * @throws Exception
   */
  public void testArguments() throws Exception {
    ITargetDefinition definition = getNewTarget();

    // Add program arguments
    String programArgs = "-testProgramArgument -testProgramArgument2";
    definition.setProgramArguments(programArgs);
    assertEquals(programArgs, definition.getProgramArguments());

    // Add VM arguments
    String vmArgs = "-testVMArgument -testVMArgument2";
    definition.setVMArguments(vmArgs);
    assertEquals(vmArgs, definition.getVMArguments());

    try {
      getTargetService().saveTargetDefinition(definition);
      setTargetPlatform(definition);

      // Check that new launch configs will be prepopulated from target
      assertEquals(vmArgs, LaunchArgumentsHelper.getInitialVMArguments());
      assertEquals(
          "-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl} -consoleLog "
              .concat(programArgs),
          LaunchArgumentsHelper.getInitialProgramArguments());

    } finally {
      getTargetService().deleteTarget(definition.getHandle());
      resetTargetPlatform();
    }
  }
  /**
   * Tests that a bundle directory container is equivalent to scanning locations when it uses a
   * variable to specify its location.
   *
   * @throws Exception
   */
  public void testVariableDirectoryBundleContainer() throws Exception {
    // the new way
    ITargetDefinition definition = getNewTarget();
    ITargetLocation container = getTargetService().newDirectoryLocation("${eclipse_home}/plugins");
    definition.setTargetLocations(new ITargetLocation[] {container});
    Set urls = getAllBundleURLs(definition);

    Preferences store = PDECore.getDefault().getPluginPreferences();
    boolean restore = store.getBoolean(ICoreConstants.TARGET_PLATFORM_REALIZATION);
    try {
      store.setValue(ICoreConstants.TARGET_PLATFORM_REALIZATION, false);
      // the old way
      URL[] pluginPaths = PluginPathFinder.getPluginPaths(TargetPlatform.getDefaultLocation());
      assertEquals("Should have same number of bundles", pluginPaths.length, urls.size());
      for (int i = 0; i < pluginPaths.length; i++) {
        URL url = pluginPaths[i];
        assertTrue("Missing plug-in " + url.toString(), urls.contains(url));
      }
    } finally {
      store.setValue(ICoreConstants.TARGET_PLATFORM_REALIZATION, restore);
    }
  }
  /**
   * Set the container to display in the tree or <code>null</code> to disable the tree
   *
   * @param input bundle container or <code>null</code>
   */
  public void setInput(ITargetDefinition input) {
    fTargetDefinition = input;

    // Update the cached data
    fFileBundleMapping = null;
    fAllBundles.clear();

    if (input == null || !input.isResolved()) {
      fTree.setInput(Messages.TargetContentsGroup_10);
      setEnabled(false);
      return;
    }

    IResolvedBundle[] allResolvedBundles = input.getAllBundles();
    if (allResolvedBundles == null || allResolvedBundles.length == 0) {
      fTree.setInput(Messages.TargetContentsGroup_11);
      setEnabled(false);
      return;
    }

    for (int i = 0; i < allResolvedBundles.length; i++) {
      fAllBundles.add(allResolvedBundles[i]);
    }

    boolean isFeatureMode =
        ((TargetDefinition) fTargetDefinition).getUIMode() == TargetDefinition.MODE_FEATURE;
    fFeaureModeButton.setSelection(isFeatureMode);
    fPluginModeButton.setSelection(!isFeatureMode);
    fGroupLabel.setEnabled(!isFeatureMode);

    fTree.getControl().setRedraw(false);
    fTree.setInput(fTargetDefinition);
    fTree.expandAll();
    updateCheckState();
    updateButtons();
    setEnabled(true);
    fTree.getControl().setRedraw(true);
  }
  protected void doIncludeVersions(NameVersionDescriptor[] descriptions) throws Exception {
    String bsn = MULTI_VERSION_LOW_DESCRIPTION.getId();

    IPath extras = extractMultiVersionPlugins();
    ITargetDefinition target = getNewTarget();
    ITargetLocation container = getTargetService().newDirectoryLocation(extras.toOSString());
    target.setTargetLocations(new ITargetLocation[] {container});
    target.setIncluded(descriptions);
    try {
      getTargetService().saveTargetDefinition(target);
      setTargetPlatform(target);
      IPluginModelBase[] models = PluginRegistry.getExternalModels();
      Set enabled = new HashSet();
      for (int i = 0; i < models.length; i++) {
        IPluginModelBase pm = models[i];
        if (pm.getBundleDescription().getSymbolicName().equals(bsn)) {
          NameVersionDescriptor desc =
              new NameVersionDescriptor(
                  pm.getPluginBase().getId(), pm.getPluginBase().getVersion());
          if (pm.isEnabled()) {
            enabled.add(desc);
          }
        }
      }
      if (descriptions == null) {

      } else {
        assertEquals("Wrong number of enabled bundles", descriptions.length, enabled.size());
        for (int i = 0; i < descriptions.length; i++) {
          assertTrue("Missing bundle", enabled.contains(descriptions[i]));
        }
      }
    } finally {
      getTargetService().deleteTarget(target.getHandle());
      resetTargetPlatform();
    }
  }
  /**
   * Tests that a target definition based on the default target platform restricted to a subset of
   * bundles contains the right set. In this case empty, since the versions specified are bogus.
   *
   * @throws Exception
   */
  public void testMissingVersionRestrictedDefaultTargetPlatform() throws Exception {
    ITargetDefinition definition = getNewTarget();
    ITargetLocation container =
        getTargetService().newProfileLocation(TargetPlatform.getDefaultLocation(), null);
    NameVersionDescriptor[] restrictions =
        new NameVersionDescriptor[] {
          new NameVersionDescriptor("org.eclipse.jdt.launching", "xyz"),
          new NameVersionDescriptor("org.eclipse.jdt.debug", "abc")
        };
    definition.setTargetLocations(new ITargetLocation[] {container});
    definition.setIncluded(restrictions);
    definition.resolve(null);
    TargetBundle[] bundles = definition.getBundles();

    assertEquals("Wrong number of bundles", 2, bundles.length);
    for (int i = 0; i < bundles.length; i++) {
      TargetBundle rb = bundles[i];
      assertEquals(
          "Should be a missing bundle version",
          TargetBundle.STATUS_VERSION_DOES_NOT_EXIST,
          rb.getStatus().getCode());
      assertEquals("Should be an error", IStatus.ERROR, rb.getStatus().getSeverity());
    }
  }
  /**
   * Tests that a target definition based on the JDT feature restricted to a subset of bundles
   * contains the right set.
   *
   * @throws Exception
   */
  public void testRestrictedFeatureBundleContainer() throws Exception {
    // extract the feature
    IPath location = extractModifiedFeatures();

    ITargetDefinition definition = getNewTarget();
    ITargetLocation container =
        getTargetService().newFeatureLocation(location.toOSString(), "org.eclipse.jdt", null);
    NameVersionDescriptor[] restrictions =
        new NameVersionDescriptor[] {
          new NameVersionDescriptor("org.eclipse.jdt", null),
          new NameVersionDescriptor("org.junit", "3.8.2.v20090203-1005")
        };
    definition.setTargetLocations(new ITargetLocation[] {container});
    definition.setIncluded(restrictions);
    List infos = getAllBundleInfos(definition);

    assertEquals("Wrong number of bundles", 2, infos.size());
    Set set = collectAllSymbolicNames(infos);
    for (int i = 0; i < restrictions.length; i++) {
      NameVersionDescriptor info = restrictions[i];
      set.remove(info.getId());
    }
    assertEquals("Wrong bundles", 0, set.size());
  }
 private void updateCheckState() {
   List result = new ArrayList();
   // Checked error statuses
   if (fMissing != null) {
     result.addAll(fMissing);
   }
   if (fFeaureModeButton.getSelection()) {
     // Checked features and plugins
     result.addAll(((TargetDefinition) fTargetDefinition).getFeaturesAndBundles());
   } else {
     // Bundles with errors are already included from fMissing, do not add twice
     IResolvedBundle[] bundles = fTargetDefinition.getBundles();
     for (int i = 0; i < bundles.length; i++) {
       if (bundles[i].getStatus().isOK()) {
         result.add(bundles[i]);
       }
     }
   }
   fTree.setCheckedElements(result.toArray());
 }
  public void saveIncludedBundleState() {
    if (fFeaureModeButton.getSelection()) {
      // Create a list of checked bundle infos
      List included = new ArrayList();
      int missingCount = 0;
      Object[] checked = fTree.getCheckedLeafElements();
      for (int i = 0; i < checked.length; i++) {
        if (checked[i] instanceof IFeatureModel) {
          included.add(
              new NameVersionDescriptor(
                  ((IFeatureModel) checked[i]).getFeature().getId(),
                  null,
                  NameVersionDescriptor.TYPE_FEATURE));
        }
        if (checked[i] instanceof IResolvedBundle) {
          // Missing features are included as IResolvedBundles, save them as features instead
          if (((IResolvedBundle) checked[i]).getStatus().getCode()
              == IResolvedBundle.STATUS_PLUGIN_DOES_NOT_EXIST) {
            included.add(
                new NameVersionDescriptor(
                    ((IResolvedBundle) checked[i]).getBundleInfo().getSymbolicName(),
                    null,
                    NameVersionDescriptor.TYPE_PLUGIN));
            missingCount++;
          } else if (((IResolvedBundle) checked[i]).getStatus().getCode()
              == IResolvedBundle.STATUS_FEATURE_DOES_NOT_EXIST) {
            included.add(
                new NameVersionDescriptor(
                    ((IResolvedBundle) checked[i]).getBundleInfo().getSymbolicName(),
                    null,
                    NameVersionDescriptor.TYPE_FEATURE));
            missingCount++;
          } else {
            included.add(
                new NameVersionDescriptor(
                    ((IResolvedBundle) checked[i]).getBundleInfo().getSymbolicName(), null));
          }
        }
      }

      if (included.size() == 0) {
        fTargetDefinition.setIncluded(new NameVersionDescriptor[0]);
      } else if (included.size() == 0
          || included.size() - missingCount
              == fTargetDefinition.getAllFeatures().length
                  + ((TargetDefinition) fTargetDefinition).getOtherBundles().length) {
        fTargetDefinition.setIncluded(null);
      } else {
        fTargetDefinition.setIncluded(
            (NameVersionDescriptor[]) included.toArray(new NameVersionDescriptor[included.size()]));
      }
    } else {
      // Figure out if there are multiple bundles sharing the same id
      Set multi = new HashSet(); // BSNs of bundles with multiple versions available
      Set all = new HashSet();
      for (Iterator iterator = fAllBundles.iterator(); iterator.hasNext(); ) {
        IResolvedBundle rb = (IResolvedBundle) iterator.next();
        if (!all.add(rb.getBundleInfo().getSymbolicName())) {
          multi.add(rb.getBundleInfo().getSymbolicName());
        }
      }

      // Create a list of checked bundle infos
      List included = new ArrayList();
      Object[] checked = fTree.getCheckedLeafElements();
      for (int i = 0; i < checked.length; i++) {
        if (checked[i] instanceof IResolvedBundle) {
          // Create the bundle info object
          String bsn = ((IResolvedBundle) checked[i]).getBundleInfo().getSymbolicName();
          NameVersionDescriptor info = null;
          if (multi.contains(bsn)) {
            // include version info
            info =
                new NameVersionDescriptor(
                    bsn, ((IResolvedBundle) checked[i]).getBundleInfo().getVersion());
          } else {
            // don't store version info
            info = new NameVersionDescriptor(bsn, null);
          }
          included.add(info);
        }
      }

      if (included.size() == 0) {
        fTargetDefinition.setIncluded(new NameVersionDescriptor[0]);
      } else if (included.size() == fAllBundles.size() + fMissing.size()) {
        fTargetDefinition.setIncluded(null);
      } else {
        fTargetDefinition.setIncluded(
            (NameVersionDescriptor[]) included.toArray(new NameVersionDescriptor[included.size()]));
      }
    }
  }
  private void updateButtons() {
    if (fTargetDefinition != null && !fTree.getSelection().isEmpty()) {
      Object[] selection = ((IStructuredSelection) fTree.getSelection()).toArray();
      boolean hasResolveBundle = false;
      boolean hasParent = false;
      boolean allSelected = true;
      boolean noneSelected = true;
      for (int i = 0; i < selection.length; i++) {
        if (!hasResolveBundle || !hasParent) {
          if (selection[i] instanceof IResolvedBundle) {
            hasResolveBundle = true;
          } else {
            hasParent = true;
          }
        }
        boolean checked = fTree.getChecked(selection[i]);
        if (checked) {
          noneSelected = false;
        } else {
          allSelected = false;
        }
      }
      // Selection is available if not everything is already selected and not both a parent and
      // child item are selected
      fSelectButton.setEnabled(!allSelected && !(hasResolveBundle && hasParent));
      fDeselectButton.setEnabled(!noneSelected && !(hasResolveBundle && hasParent));
    } else {
      fSelectButton.setEnabled(false);
      fDeselectButton.setEnabled(false);
    }

    int total = fAllBundles.size();
    if (fFeaureModeButton.getSelection()) {
      if (fTargetDefinition == null) {
        total = 0;
      } else {
        total = fTargetDefinition.getAllFeatures().length;
        total += ((TargetDefinition) fTargetDefinition).getOtherBundles().length;
      }
    }
    if (fMissing != null) {
      total += fMissing.size();
    }

    fSelectAllButton.setEnabled(fTargetDefinition != null && fTree.getCheckedLeafCount() != total);
    fDeselectAllButton.setEnabled(fTargetDefinition != null && fTree.getCheckedLeafCount() != 0);
    fSelectRequiredButton.setEnabled(
        fTargetDefinition != null
            && fTree.getCheckedLeafCount() > 0
            && fTree.getCheckedLeafCount() != total);

    if (fTargetDefinition != null) {
      fCountLabel.setText(
          MessageFormat.format(
              Messages.TargetContentsGroup_9,
              new String[] {
                Integer.toString(fTree.getCheckedLeafCount()), Integer.toString(total)
              }));
    } else {
      fCountLabel.setText(""); // $NON-NLS-1$
    }
  }