private ISiteFeature[] getFeaturesFromSelection(IStructuredSelection sel) {
   if (sel.isEmpty()) return new ISiteFeature[0];
   if (cachedSelection == sel) return cachedFeatures;
   cachedSelection = sel;
   ArrayList<ISiteFeature> features = new ArrayList<ISiteFeature>(sel.size());
   Iterator<?> iterator = sel.iterator();
   while (iterator.hasNext()) {
     Object next = iterator.next();
     if (next instanceof SiteFeatureAdapter) {
       if ((((SiteFeatureAdapter) next).feature) != null) {
         features.add(((SiteFeatureAdapter) next).feature);
       }
     }
   }
   cachedFeatures = features.toArray(new ISiteFeature[features.size()]);
   return cachedFeatures;
 }
 protected void handleDoubleClick(IStructuredSelection ssel) {
   super.handleDoubleClick(ssel);
   Object selected = ssel.getFirstElement();
   if (selected instanceof SiteFeatureAdapter) {
     IFeature feature = findFeature(((SiteFeatureAdapter) selected).feature);
     FeatureEditor.openFeatureEditor(feature);
   }
 }
  private boolean handleRemove() {
    IStructuredSelection ssel = (IStructuredSelection) fCategoryViewer.getSelection();
    Iterator<?> iterator = ssel.iterator();
    boolean success = true;
    Set<?> removedCategories = new HashSet<Object>();
    while (iterator.hasNext()) {
      Object object = iterator.next();
      if (object == null) continue;
      if (object instanceof ISiteCategoryDefinition) {
        if (!handleRemoveCategoryDefinition((ISiteCategoryDefinition) object)) {
          success = false;
        }
      } else {
        // check if some of features was not removed during category removal
        SiteFeatureAdapter fa = (SiteFeatureAdapter) object;
        if (removedCategories.contains(fa.category)) continue;

        if (!handleRemoveSiteFeatureAdapter(fa)) {
          success = false;
        }
      }
    }
    return success;
  }