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$
    }
  }
  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()]));
      }
    }
  }