@Override
 public void propertyChange(PropertyChangeEvent evt) {
   int index = model.getDataProviders().indexOf(evt.getSource());
   if (index != -1) {
     viewer.getTree().getColumn(index + 1).setText((String) evt.getNewValue());
   }
 }
 /* (non-Javadoc)
  * @see org.eclipse.ui.part.WorkbenchPart#getAdapter(java.lang.Class)
  */
 @Override
 @SuppressWarnings({"unchecked", "rawtypes"})
 public Object getAdapter(Class adapter) {
   if (adapter.isAssignableFrom(model.getClass())) {
     return model;
   }
   return super.getAdapter(adapter);
 }
 @Override
 public void controlResized(ControlEvent e) {
   IDialogSettings settings = dialogSettings.getSection(COLUMN_WIDTHS);
   TreeColumn treeColumn = (TreeColumn) e.widget;
   int index = treeColumn.getParent().indexOf(treeColumn);
   if (index == 0) {
     settings.put(LABEL_COLUMN, treeColumn.getWidth());
   } else {
     ViewColumn viewColumn = model.getDataProviders().get(index - 1);
     settings.put(viewColumn.getDataProviderFactory().getId(), treeColumn.getWidth());
   }
 }
 /* (non-Javadoc)
  * @see org.eclipse.ui.part.WorkbenchPart#dispose()
  */
 @Override
 public void dispose() {
   model.dispose();
   super.dispose();
 }
  /* (non-Javadoc)
   * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
   */
  @Override
  public void createPartControl(Composite parent) {
    viewer = new TreeViewer(parent, SWT.FULL_SELECTION | SWT.MULTI);
    viewer.getTree().setHeaderVisible(true);
    viewer.getTree().setLinesVisible(false);

    createContextMenu();

    model = new TradingSystemsViewModel(tradingSystemService);

    String[] columns = dialogSettings.getArray(COLUMNS);
    IDialogSettings namesSection = dialogSettings.getSection(COLUMN_NAMES);

    List<ViewColumn> list = new ArrayList<ViewColumn>();
    for (int i = 0; i < columns.length; i++) {
      String name = namesSection.get(columns[i]);
      list.add(new ViewColumn(name, activator.getDataProviderFactory(columns[i])));
    }
    model.setDataProviders(list);

    for (final TradingSystemItem item : model.getList()) {
      PropertyChangeSupport changeSupport =
          (PropertyChangeSupport) item.getTradingSystem().getAdapter(PropertyChangeSupport.class);
      if (changeSupport != null) {
        changeSupport.addPropertyChangeListener(
            new PropertyChangeListener() {

              @Override
              public void propertyChange(PropertyChangeEvent evt) {
                Display.getDefault()
                    .asyncExec(
                        new Runnable() {

                          @Override
                          public void run() {
                            if (viewer.getControl().isDisposed()) {
                              return;
                            }
                            viewer.refresh(item);
                          }
                        });
              }
            });
      }
    }

    final ObservableListTreeContentProvider contentProvider =
        new ObservableListTreeContentProvider(model, model);
    viewer.setContentProvider(contentProvider);

    IDialogSettings widthSettings = dialogSettings.getSection(COLUMN_WIDTHS);

    TreeViewerColumn viewerColumn = new TreeViewerColumn(viewer, SWT.NONE);

    int width = 300;
    if (widthSettings.get(LABEL_COLUMN) != null) {
      width = widthSettings.getInt(LABEL_COLUMN);
    }
    viewerColumn.getColumn().setWidth(width);

    viewerColumn.getColumn().addControlListener(columnControlListener);

    final List<IObservableMap> properties = new ArrayList<IObservableMap>();
    properties.add(new ViewerObservableMap(contentProvider.getKnownElements(), LABEL_COLUMN));
    for (ViewColumn column : model.getDataProviders()) {
      viewerColumn = new TreeViewerColumn(viewer, SWT.RIGHT);
      viewerColumn.getColumn().setText(column.getName());

      width = 100;
      if (widthSettings.get(column.getDataProviderFactory().getId()) != null) {
        width = widthSettings.getInt(column.getDataProviderFactory().getId());
      }
      viewerColumn.getColumn().setWidth(width);

      viewerColumn.getColumn().addControlListener(columnControlListener);
      column.addPropertyChangeListener(ViewColumn.PROP_NAME, columnPropertiesChangeListener);
      properties.add(
          new ViewerObservableMap(
              contentProvider.getKnownElements(), column.getDataProviderFactory().getId()));
    }
    createLabelProvider(properties.toArray(new IObservableMap[properties.size()]));

    model
        .getObservableDataProviders()
        .addListChangeListener(
            new IListChangeListener() {

              @Override
              public void handleListChange(ListChangeEvent event) {
                event.diff.accept(
                    new ListDiffVisitor() {

                      @Override
                      public void handleRemove(int index, Object element) {
                        TreeColumn treeColumn = viewer.getTree().getColumn(index + 1);
                        treeColumn.dispose();

                        ViewColumn column = (ViewColumn) element;
                        column.removePropertyChangeListener(
                            ViewColumn.PROP_NAME, columnPropertiesChangeListener);

                        IObservableMap observableMap = properties.remove(index + 1);
                        if (observableMap != null) {
                          observableMap.dispose();
                        }
                      }

                      @Override
                      public void handleAdd(int index, Object element) {
                        ViewColumn column = (ViewColumn) element;
                        TreeViewerColumn viewerColumn =
                            new TreeViewerColumn(viewer, SWT.RIGHT, index + 1);
                        viewerColumn.getColumn().setText(column.getName());

                        int width = 100;
                        IDialogSettings widthSettings = dialogSettings.getSection(COLUMN_WIDTHS);
                        if (widthSettings.get(column.getDataProviderFactory().getId()) != null) {
                          width = widthSettings.getInt(column.getDataProviderFactory().getId());
                        }
                        viewerColumn.getColumn().setWidth(width);

                        viewerColumn.getColumn().addControlListener(columnControlListener);
                        column.addPropertyChangeListener(
                            ViewColumn.PROP_NAME, columnPropertiesChangeListener);
                        properties.add(
                            index + 1,
                            new ViewerObservableMap(
                                contentProvider.getKnownElements(),
                                column.getDataProviderFactory().getId()));
                      }
                    });

                createLabelProvider(properties.toArray(new IObservableMap[properties.size()]));

                IDialogSettings namesSection = dialogSettings.getSection(COLUMN_NAMES);

                List<String> list = new ArrayList<String>();
                for (ViewColumn column : model.getDataProviders()) {
                  list.add(column.getDataProviderFactory().getId());
                  namesSection.put(column.getDataProviderFactory().getId(), column.getName());
                }
                dialogSettings.put(COLUMNS, list.toArray(new String[list.size()]));
              }
            });

    viewer.setComparator(new ViewerComparator());

    getSite().setSelectionProvider(viewer);

    viewer.setInput(model);
    viewer.expandAll();
  }