private boolean applyFilters(CategorySerializable cat) {
          // Apply any filters.
          boolean include = true;
          if (filters.size() > 0) {
            for (Iterator filterIt = filters.iterator(); filterIt.hasNext(); ) {
              DatasetFilter filter = (DatasetFilter) filterIt.next();

              // This should be done with introspection, but for now do a
              // big cheat
              String name = "x";
              String value = "y";
              if (filter.getAttribute().equals("name")) {
                name = cat.getName().toLowerCase();
                value = filter.getValue().toLowerCase();

              } else if (filter.getAttribute().equals("ID")) {
                name = cat.getID();
                value = filter.getValue();
              }
              if (name.contains(value)) {
                include = include && filter.isInclude();
              } else {
                include = include && !filter.isInclude();
              }
            }
          }

          return include;
        }
 @Override
 public void onOpen(OpenEvent<TreeItem> event) {
   TreeItem item = event.getTarget();
   currentlySelected = item;
   if (item.getChild(0).getText().equals(DatasetWidget.LOADING)) {
     CategorySerializable cat = (CategorySerializable) item.getUserObject();
     Util.getRPCService().getCategories(cat.getID(), null, categoryCallback);
   }
 }
 @Override
 public void onSelection(SelectionEvent<TreeItem> event) {
   TreeItem item = event.getSelectedItem();
   currentlySelected = item;
   TreeItem child = item.getChild(0);
   if (child != null && child.getText().equals(DatasetWidget.LOADING)) {
     CategorySerializable cat = (CategorySerializable) item.getUserObject();
     Util.getRPCService().getCategories(cat.getID(), null, categoryCallback);
   }
   // Open the item.  Work around double firing bug.
   // http://code.google.com/p/google-web-toolkit/issues/detail?id=3660&q=Tree%20selection&colspec=ID%20Type%20Status%20Owner%20Milestone%20Summary%20Stars
   TreeItem selItem = event.getSelectedItem();
   TreeItem parent = selItem.getParentItem();
   selItem.getTree().setSelectedItem(parent, false); // null is ok
   if (parent != null) parent.setSelected(false); // not compulsory
   selItem.setState(!selItem.getState(), false);
 }
    public InnerItem(Serializable s) {
      close.addStyleDependentName("SMALLER");
      close.addClickHandler(
          new ClickHandler() {

            @Override
            public void onClick(ClickEvent event) {
              inner.hide();
            }
          });
      innerLayout.add(close);
      grid.getCellFormatter().setWidth(0, 0, "85%");
      grid.getCellFormatter().setWidth(0, 1, "5%");
      label.setText(s.getName());
      grid.setWidget(0, 0, label);
      if (s instanceof CategorySerializable) {
        CategorySerializable c = (CategorySerializable) s;
        if (c.getDoc() != null || c.getAttributes().get("children_dsid") != null) {
          image.addClickHandler(
              new ClickHandler() {
                @Override
                public void onClick(ClickEvent event) {
                  inner.setPopupPosition(image.getAbsoluteLeft(), image.getAbsoluteTop());
                  inner.show();
                }
              });
          grid.setWidget(0, 1, image);
          if (c.getDoc() != null) {
            String url = c.getDoc();
            if (!c.getDoc().equals("")) {
              Anchor link = new Anchor("Documentation", url, "_blank");
              innerLayout.add(link);
            }
          }
          if (c.getAttributes().get("children_dsid") != null) {
            Anchor meta =
                new Anchor(
                    "Variable and Grid Description",
                    "getMetadata.do?dsid=" + c.getAttributes().get("children_dsid"),
                    "_blank");
            innerLayout.add(meta);
          }
          inner.add(innerLayout);
        }
      }
      initWidget(grid);
    }
 public void onSuccess(Object result) {
   CategorySerializable[] cats = (CategorySerializable[]) result;
   if (cats != null && cats.length > 0) {
     if (currentlySelected == null) {
       for (int i = 0; i < cats.length; i++) {
         CategorySerializable cat = cats[i];
         String children = cat.getAttributes().get("children");
         boolean empty = false;
         if (children != null && children.equals("none")) empty = true;
         if (applyFilters(cat) && !empty) {
           TreeItem item = new TreeItem();
           item.addItem(
               new SafeHtmlBuilder().appendEscaped(DatasetWidget.LOADING).toSafeHtml());
           InnerItem inner = new InnerItem(cat);
           item.setWidget(inner);
           item.setUserObject(cat);
           addItem(item);
         }
       }
     } else {
       for (int i = 0; i < cats.length; i++) {
         CategorySerializable cat = cats[i];
         if (cat.isCategoryChildren()) {
           String name = cat.getName();
           TreeItem item;
           if (i == 0) {
             item = currentlySelected.getChild(0);
           } else {
             item = new TreeItem();
           }
           item.addItem(
               new SafeHtmlBuilder().appendEscaped(DatasetWidget.LOADING).toSafeHtml());
           InnerItem inner = new InnerItem(cat);
           item.setWidget(inner);
           item.setUserObject(cat);
           if (i > 0) {
             currentlySelected.addItem(item);
           }
         } else if (cat.isVariableChildren()) {
           // Must have variable children...
           TreeItem item = currentlySelected.getChild(0);
           if (cat.hasMultipleDatasets()) {
             DatasetSerializable[] dses = cat.getDatasetSerializableArray();
             DatasetSerializable ds = dses[0];
             VariableSerializable[] vars = ds.getVariablesSerializable();
             currentlySelected.removeItems();
             for (int j = 0; j < dses.length; j++) {
               ds = dses[j];
               vars = ds.getVariablesSerializable();
               loadItem(vars);
             }
           } else {
             DatasetSerializable ds = cat.getDatasetSerializable();
             VariableSerializable[] vars = ds.getVariablesSerializable();
             currentlySelected.removeItems();
             loadItem(vars);
           }
         }
       }
     }
   } else {
     // A category was selected, but it came back empty...
     if (currentlySelected != null) {
       TreeItem item = currentlySelected.getChild(0);
       item.setText("No data sets found.");
     }
   }
   if (saveSelection != null) {
     currentlySelected = saveSelection;
     saveSelection = null;
   }
 }