public void gotValue(
     LiveExpression<Filter<BootDashElement>> exp, Filter<BootDashElement> value) {
   tv.refresh();
   final Tree t = tv.getTree();
   t.getDisplay()
       .asyncExec(
           new Runnable() {
             public void run() {
               Composite parent = t.getParent();
               parent.layout();
             }
           });
 }
  @Override
  public void createContents(Composite page) {
    tv = new CustomTreeViewer(page, SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI);
    tv.setExpandPreCheckFilters(true);
    tv.setContentProvider(new BootDashTreeContentProvider());
    tv.setSorter(new BootModelViewerSorter(this.model));
    tv.setInput(model);
    tv.getTree().setLinesVisible(true);

    stylers = new Stylers(tv.getTree().getFont());
    tv.setLabelProvider(new BootDashTreeLabelProvider(stylers, tv));

    ColumnViewerToolTipSupport.enableFor(tv);

    GridDataFactory.fillDefaults().grab(true, true).applyTo(tv.getTree());

    new HiddenElementsLabel(page, tv.hiddenElementCount);

    tv.getControl()
        .addControlListener(
            new ControlListener() {
              public void controlResized(ControlEvent e) {
                ReflowUtil.reflow(owner, tv.getControl());
              }

              public void controlMoved(ControlEvent e) {}
            });

    actions = new BootDashActions(model, getSelection(), getSectionSelection(), ui);
    hookContextMenu();

    // Careful, either selection or tableviewer might be created first.
    // in either case we must make sure the listener is added when *both*
    // have been created.
    if (selection != null) {
      addViewerSelectionListener();
    }

    tv.addDoubleClickListener(
        new IDoubleClickListener() {
          public void doubleClick(DoubleClickEvent event) {
            if (selection != null) {
              BootDashElement selected = selection.getSingle();
              if (selected != null) {
                String url =
                    BootDashElementUtil.getUrl(selected, selected.getDefaultRequestMappingPath());
                if (url != null) {
                  UiUtil.openUrl(url);
                }
              } else if (sectionSelection.getValue() != null) {
                IAction openCloudAdminConsoleAction = actions.getOpenCloudAdminConsoleAction();
                if (openCloudAdminConsoleAction != null) {
                  openCloudAdminConsoleAction.run();
                }
              }
            }
          }
        });

    model.getRunTargets().addListener(RUN_TARGET_LISTENER);
    model.getSectionModels().addListener(ELEMENTS_SET_LISTENER_ADAPTER);

    model.addElementStateListener(ELEMENT_STATE_LISTENER);

    if (searchFilterModel != null) {
      searchFilterModel.addListener(FILTER_LISTENER);
      tv.addFilter(
          new ViewerFilter() {
            @Override
            public boolean select(Viewer viewer, Object parentElement, Object element) {
              if (searchFilterModel.getValue() != null && element instanceof BootDashElement) {
                return searchFilterModel.getValue().accept((BootDashElement) element);
              }
              return true;
            }
          });
    }

    tv.getTree()
        .addDisposeListener(
            new DisposeListener() {
              @Override
              public void widgetDisposed(DisposeEvent e) {
                model.removeElementStateListener(ELEMENT_STATE_LISTENER);
                model.getRunTargets().removeListener(RUN_TARGET_LISTENER);
                model.getSectionModels().removeListener(ELEMENTS_SET_LISTENER_ADAPTER);
                for (BootDashModel m : model.getSectionModels().getValue()) {
                  m.removeModelStateListener(MODEL_STATE_LISTENER);
                }

                if (searchFilterModel != null) {
                  searchFilterModel.removeListener(FILTER_LISTENER);
                }

                if (actions != null) {
                  actions.dispose();
                  actions = null;
                }
                if (stylers != null) {
                  stylers.dispose();
                  stylers = null;
                }
              }
            });

    addDragSupport(tv);
    addDropSupport(tv);
  }