/*******************************************************************************
 * Copyright (c) 2008-2010 Sonatype, Inc.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *      Sonatype, Inc. - initial API and implementation
 *******************************************************************************/

package org.eclipse.m2e.editor.pom;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.eclipse.aether.graph.DependencyNode;
import org.eclipse.aether.graph.DependencyVisitor;
import org.eclipse.aether.util.graph.manager.DependencyManagerUtils;
import org.eclipse.aether.util.graph.transformer.ConflictResolver;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuCreator;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.IColorProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.editor.FormPage;
import org.eclipse.ui.forms.widgets.ExpandableComposite;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.progress.UIJob;
import org.eclipse.ui.progress.WorkbenchJob;
import org.eclipse.ui.services.IDisposable;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
import org.apache.maven.project.MavenProject;

import org.eclipse.m2e.core.MavenPlugin;
import org.eclipse.m2e.core.embedder.ArtifactKey;
import org.eclipse.m2e.core.internal.IMavenConstants;
import org.eclipse.m2e.core.internal.MavenPluginActivator;
import org.eclipse.m2e.core.project.IMavenProjectChangedListener;
import org.eclipse.m2e.core.project.IMavenProjectFacade;
import org.eclipse.m2e.core.project.IMavenProjectRegistry;
import org.eclipse.m2e.core.project.MavenProjectChangedEvent;
import org.eclipse.m2e.core.ui.internal.actions.OpenPomAction;
import org.eclipse.m2e.editor.MavenEditorImages;
import org.eclipse.m2e.editor.internal.Messages;


/**
 * @author Eugene Kuleshov
 * @author Benjamin Bentmann
 */
public class DependencyTreePage extends FormPage implements IMavenProjectChangedListener, IPomFileChangedListener {
  private static final Logger log = LoggerFactory.getLogger(DependencyTreePage.class);

  protected static final Object[] EMPTY = new Object[0];

  final MavenPomEditor pomEditor;

  TreeViewer treeViewer;

  TableViewer listViewer;

  SearchControl searchControl;

  SearchMatcher searchMatcher;

  DependencyFilter searchFilter;

  ListSelectionFilter listSelectionFilter;

  ViewerFilter currentFilter;

  ArrayList<DependencyNode> dependencyNodes = new ArrayList<DependencyNode>();

  Highlighter highlighter;

  MavenProject mavenProject;

  boolean isSettingSelection = false;

  Action hierarchyFilterAction;

  private Job dataLoadingJob;

  String currentClasspath = Artifact.SCOPE_TEST;

  public DependencyTreePage(MavenPomEditor pomEditor) {
    super(pomEditor, IMavenConstants.PLUGIN_ID + ".pom.dependencyTree", Messages.DependencyTreePage_title); //$NON-NLS-1$
    this.pomEditor = pomEditor;
  }

  protected void createFormContent(IManagedForm managedForm) {
    MavenPluginActivator.getDefault().getMavenProjectManager().addMavenProjectChangedListener(this);

    FormToolkit formToolkit = managedForm.getToolkit();

    ScrolledForm form = managedForm.getForm();
    form.setText(formatFormTitle());
    form.setExpandHorizontal(true);
    form.setExpandVertical(true);

    Composite body = form.getBody();
    body.setLayout(new FillLayout());

    SashForm sashForm = new SashForm(body, SWT.NONE);
    formToolkit.adapt(sashForm);
    formToolkit.adapt(sashForm, true, true);

    highlighter = new Highlighter();

    createHierarchySection(sashForm, formToolkit);

    createListSection(sashForm, formToolkit);

    sashForm.setWeights(new int[] {1, 1});

    createSearchBar(managedForm);

    // compatibility proxy to support Eclipse 3.2
    FormUtils.decorateHeader(managedForm.getToolkit(), form.getForm());

    initPopupMenu(treeViewer, ".tree"); //$NON-NLS-1$
    initPopupMenu(listViewer, ".list"); //$NON-NLS-1$

    loadData(false);
  }

  private void initPopupMenu(Viewer viewer, String id) {
    MenuManager menuMgr = new MenuManager("#PopupMenu-" + id); //$NON-NLS-1$
    menuMgr.setRemoveAllWhenShown(true);

    Menu menu = menuMgr.createContextMenu(viewer.getControl());

    viewer.getControl().setMenu(menu);

    getEditorSite().registerContextMenu(MavenPomEditor.EDITOR_ID + id, menuMgr, viewer, false);
  }

  String formatFormTitle() {
    return NLS.bind(Messages.DependencyTreePage_form_title, currentClasspath);
  }

  void loadData(final boolean force) {
    // form.setMessage() forces the panel layout, which messes up the viewers
    // (e.g. long entries in the tree cause it to expand horizontally so much
    // doesn't fit into the editor anymore). Clearing the input in the viewers
    // helps to ensure they won't change the size when the message is set.
    if(treeViewer.getTree().isDisposed()) {
      return;
    }
    treeViewer.setInput(null);
    if(listViewer.getTable().isDisposed()) {
      return;
    }
    listViewer.setInput(null);
    FormUtils.setMessage(getManagedForm().getForm(), Messages.DependencyTreePage_message_resolving,
        IMessageProvider.WARNING);

    dataLoadingJob = new Job(Messages.DependencyTreePage_job_loading) {
      protected IStatus run(IProgressMonitor monitor) {
        try {
          mavenProject = pomEditor.readMavenProject(force, monitor);
          if(mavenProject == null) {
            log.error("Unable to read maven project. Dependencies not updated."); //$NON-NLS-1$
            return Status.CANCEL_STATUS;
          }

          final DependencyNode dependencyNode = pomEditor.readDependencyTree(force, currentClasspath, monitor);
          if(dependencyNode == null) {
            return Status.CANCEL_STATUS;
          }
          dependencyNode.accept(new DependencyVisitor() {
            public boolean visitEnter(DependencyNode node) {
              if(node.getDependency() != null) {
                dependencyNodes.add(node);
              }
              return true;
            }

            public boolean visitLeave(DependencyNode dependencynode) {
              return true;
            }
          });

          getPartControl().getDisplay().syncExec(() -> {
            FormUtils.setMessage(getManagedForm().getForm(), null, IMessageProvider.NONE);
            if(treeViewer.getTree().isDisposed()) {
              return;
            }

            treeViewer.setInput(dependencyNode);
            treeViewer.getTree().setRedraw(false);
            try {
              treeViewer.expandAll();
            } finally {
              treeViewer.getTree().setRedraw(true);
            }
            if(listViewer.getTable().isDisposed()) {
              return;
            }
            listViewer.setInput(mavenProject);
          });
        } catch(final CoreException ex) {
          log.error(ex.getMessage(), ex);
          getPartControl().getDisplay().asyncExec(
              () -> FormUtils.setMessage(getManagedForm().getForm(), ex.getMessage(), IMessageProvider.ERROR));
        }

        return Status.OK_STATUS;
      }
    };
    dataLoadingJob.schedule();
  }

  private void createHierarchySection(Composite sashForm, FormToolkit formToolkit) {
    Composite hierarchyComposite = formToolkit.createComposite(sashForm, SWT.NONE);
    hierarchyComposite.setLayout(new GridLayout());

    Section hierarchySection = formToolkit.createSection(hierarchyComposite, ExpandableComposite.TITLE_BAR);
    hierarchySection.marginHeight = 1;
    GridData gd_hierarchySection = new GridData(SWT.FILL, SWT.FILL, true, true);
    gd_hierarchySection.widthHint = 100;
    gd_hierarchySection.minimumWidth = 100;
    hierarchySection.setLayoutData(gd_hierarchySection);
    hierarchySection.setText(Messages.DependencyTreePage_section_hierarchy);
    formToolkit.paintBordersFor(hierarchySection);

    Tree tree = formToolkit.createTree(hierarchySection, SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI);
    hierarchySection.setClient(tree);

    treeViewer = new TreeViewer(tree);
    treeViewer.setData(FormToolkit.KEY_DRAW_BORDER, Boolean.TRUE);

    DependencyTreeLabelProvider treeLabelProvider = new DependencyTreeLabelProvider();
    treeViewer.setContentProvider(new DependencyTreeContentProvider());
    treeViewer.setLabelProvider(treeLabelProvider);

    treeViewer.addSelectionChangedListener(event -> {
      if(!isSettingSelection) {
        isSettingSelection = true;
        IStructuredSelection selection = (IStructuredSelection) treeViewer.getSelection();
        selectListElements(new DependencyNodeMatcher(selection));
        isSettingSelection = false;
      }
    });

    treeViewer.addOpenListener(event -> {
      IStructuredSelection selection = (IStructuredSelection) treeViewer.getSelection();
      for(Iterator<?> it = selection.iterator(); it.hasNext();) {
        Object o = it.next();
        if(o instanceof DependencyNode) {
          org.eclipse.aether.artifact.Artifact a = ((DependencyNode) o).getDependency().getArtifact();
          OpenPomAction.openEditor(a.getGroupId(), a.getArtifactId(), a.getVersion(), mavenProject, null);
        }
      }
    });

    createHierarchyToolbar(hierarchySection, treeLabelProvider, formToolkit);
  }

  private void createHierarchyToolbar(Section hierarchySection, final DependencyTreeLabelProvider treeLabelProvider,
      FormToolkit formToolkit) {
    ToolBarManager hiearchyToolBarManager = new ToolBarManager(SWT.FLAT);

    hiearchyToolBarManager
        .add(new Action(Messages.DependencyTreePage_action_collapseAll, MavenEditorImages.COLLAPSE_ALL) {
          public void run() {
            treeViewer.getTree().setRedraw(false);
            try {
              treeViewer.collapseAll();
            } finally {
              treeViewer.getTree().setRedraw(true);
            }
          }
        });

    hiearchyToolBarManager.add(new Action(Messages.DependencyTreePage_action_expandAll, MavenEditorImages.EXPAND_ALL) {
      public void run() {
        treeViewer.getTree().setRedraw(false);
        try {
          treeViewer.expandAll();
        } finally {
          treeViewer.getTree().setRedraw(true);
        }
      }
    });

    hiearchyToolBarManager.add(new Separator());

    hiearchyToolBarManager.add(new Action(Messages.DependencyTreePage_action_sort, MavenEditorImages.SORT) {
      public int getStyle() {
        return AS_CHECK_BOX;
      }

      public void run() {
        if(treeViewer.getComparator() == null) {
          treeViewer.setComparator(new ViewerComparator());
        } else {
          treeViewer.setComparator(null);
        }
      }
    });

    hiearchyToolBarManager
        .add(new Action(Messages.DependencyTreePage_action_showGroupId, MavenEditorImages.SHOW_GROUP) {
          public int getStyle() {
            return AS_CHECK_BOX;
          }

          public void run() {
            treeLabelProvider.setShowGroupId(isChecked());
            treeViewer.refresh();
          }
        });

    hierarchyFilterAction = new Action(Messages.DependencyTreePage_action_filterSearch, MavenEditorImages.FILTER) {
      public int getStyle() {
        return AS_CHECK_BOX;
      }

      public void run() {
        if(isChecked()) {
          setTreeFilter(currentFilter, true);
//          treeViewer.setFilters(new ViewerFilter[] {searchFilter, listSelectionFilter});
        } else {
          treeViewer.removeFilter(searchFilter);
        }
        treeViewer.getTree().setRedraw(false);
        try {
          treeViewer.refresh();
          treeViewer.expandAll();
        } finally {
          treeViewer.getTree().setRedraw(true);
        }
      }
    };
    hierarchyFilterAction.setChecked(true);
    hiearchyToolBarManager.add(hierarchyFilterAction);

    Composite toolbarComposite = formToolkit.createComposite(hierarchySection);
    toolbarComposite.setBackground(null);
    RowLayout rowLayout = new RowLayout();
    rowLayout.wrap = false;
    rowLayout.marginRight = 0;
    rowLayout.marginLeft = 0;
    rowLayout.marginTop = 0;
    rowLayout.marginBottom = 0;
    toolbarComposite.setLayout(rowLayout);

    hiearchyToolBarManager.createControl(toolbarComposite);
    hierarchySection.setTextClient(toolbarComposite);
  }

  private void createListSection(SashForm sashForm, FormToolkit formToolkit) {
    Composite listComposite = formToolkit.createComposite(sashForm, SWT.NONE);
    listComposite.setLayout(new GridLayout());

    Section listSection = formToolkit.createSection(listComposite, ExpandableComposite.TITLE_BAR);
    listSection.marginHeight = 1;
    GridData gd_listSection = new GridData(SWT.FILL, SWT.FILL, true, true);
    gd_listSection.widthHint = 100;
    gd_listSection.minimumWidth = 100;
    listSection.setLayoutData(gd_listSection);
    listSection.setText(Messages.DependencyTreePage_section_resolvedDeps);
    formToolkit.paintBordersFor(listSection);

    final DependencyListLabelProvider listLabelProvider = new DependencyListLabelProvider();

    Table table = formToolkit.createTable(listSection, SWT.FLAT | SWT.MULTI);
    listSection.setClient(table);

    // listViewer = new TableViewer(listSection, SWT.FLAT | SWT.MULTI);
    listViewer = new TableViewer(table);
    listViewer.setData(FormToolkit.KEY_DRAW_BORDER, Boolean.TRUE);
    listViewer.setContentProvider(new DependencyListContentProvider());
    listViewer.setLabelProvider(listLabelProvider);
    listViewer.setComparator(new ViewerComparator()); // by default is sorted

    listSelectionFilter = new ListSelectionFilter();
    listViewer.addSelectionChangedListener(listSelectionFilter);
    listViewer.getTable().addFocusListener(listSelectionFilter);

    listViewer.addOpenListener(event -> {
      IStructuredSelection selection = (IStructuredSelection) listViewer.getSelection();
      for(Iterator<?> it = selection.iterator(); it.hasNext();) {
        Object o = it.next();
        if(o instanceof Artifact) {
          Artifact a = (Artifact) o;
          OpenPomAction.openEditor(a.getGroupId(), a.getArtifactId(), a.getVersion(), mavenProject, null);
        }
      }
    });

    createListToolbar(listSection, listLabelProvider, formToolkit);

  }

  private void createListToolbar(Section listSection, final DependencyListLabelProvider listLabelProvider,
      FormToolkit formToolkit) {
    ToolBarManager listToolBarManager = new ToolBarManager(SWT.FLAT);

    listToolBarManager.add(new Action(Messages.DependencyTreePage_action_sort, MavenEditorImages.SORT) {
      {
        setChecked(true);
      }

      public int getStyle() {
        return AS_CHECK_BOX;
      }

      public void run() {
        if(listViewer.getComparator() == null) {
          listViewer.setComparator(new ViewerComparator());
        } else {
          listViewer.setComparator(null);
        }
      }
    });

    listToolBarManager.add(new Action(Messages.DependencyTreePage_action_showGroupId, MavenEditorImages.SHOW_GROUP) {
      public int getStyle() {
        return AS_CHECK_BOX;
      }

      public void run() {
        listLabelProvider.setShowGroupId(isChecked());
        listViewer.refresh();
      }
    });

    listToolBarManager.add(new Action(Messages.DependencyTreePage_action_filter, MavenEditorImages.FILTER) {
      public int getStyle() {
        return AS_CHECK_BOX;
      }

      public void run() {
        if(listViewer.getFilters() == null || listViewer.getFilters().length == 0) {
          listViewer.addFilter(searchFilter);
        } else {
          listViewer.removeFilter(searchFilter);
        }
      }
    });

    Composite toolbarComposite = formToolkit.createComposite(listSection);
    toolbarComposite.setBackground(null);
    RowLayout rowLayout = new RowLayout();
    rowLayout.wrap = false;
    rowLayout.marginRight = 0;
    rowLayout.marginLeft = 0;
    rowLayout.marginTop = 0;
    rowLayout.marginBottom = 0;
    toolbarComposite.setLayout(rowLayout);

    listToolBarManager.createControl(toolbarComposite);
    listSection.setTextClient(toolbarComposite);
  }

  private void createSearchBar(IManagedForm managedForm) {
    searchControl = new SearchControl(Messages.DependencyTreePage_find, managedForm);
    searchMatcher = new SearchMatcher(searchControl);
    searchFilter = new DependencyFilter(new SearchMatcher(searchControl));
    treeViewer.addFilter(searchFilter); // by default is filtered

    ScrolledForm form = managedForm.getForm();

    IToolBarManager toolBarManager = form.getForm().getToolBarManager();
    toolBarManager.add(searchControl);

    class ClasspathDropdown extends Action implements IMenuCreator {
      private Menu menu;

      public ClasspathDropdown() {
        setText(Messages.DependencyTreePage_classpath);
        setImageDescriptor(MavenEditorImages.SCOPE);
        setMenuCreator(this);
      }

      public Menu getMenu(Menu parent) {
        return null;
      }

      public Menu getMenu(Control parent) {
        if(menu != null) {
          menu.dispose();
        }

        menu = new Menu(parent);
        addToMenu(menu, Messages.DependencyTreePage_scope_all, Artifact.SCOPE_TEST, currentClasspath);
        addToMenu(menu, Messages.DependencyTreePage_scope_comp_runtime, Artifact.SCOPE_COMPILE_PLUS_RUNTIME,
            currentClasspath);
        addToMenu(menu, Messages.DependencyTreePage_scope_compile, Artifact.SCOPE_COMPILE, currentClasspath);
        addToMenu(menu, Messages.DependencyTreePage_scope_runtime, Artifact.SCOPE_RUNTIME, currentClasspath);
        return menu;
      }

      protected void addToMenu(Menu parent, String text, String scope, String currentScope) {
        ClasspathAction action = new ClasspathAction(text, scope);
        action.setChecked(scope.equals(currentScope));
        new ActionContributionItem(action).fill(parent, -1);
      }

      public void dispose() {
        if(menu != null) {
          menu.dispose();
          menu = null;
        }
      }
    }
    toolBarManager.add(new ClasspathDropdown());

    toolBarManager.add(new Separator());
    toolBarManager.add(new Action(Messages.DependencyTreePage_action_refresh, MavenEditorImages.REFRESH) {
      public void run() {
        loadData(true);
      }
    });

    form.updateToolBar();

    // Create a job to update the contents of the viewers when the
    // filter text is modified. Using a job is in this way lets us
    // defer updating the field while the user is typing.
    final Job updateJob = new WorkbenchJob("Update Maven Dependency Viewers") {
      public IStatus runInUIThread(IProgressMonitor monitor) {
        if(!listViewer.getTable().isDisposed()) {
          isSettingSelection = true;
          selectListElements(searchMatcher);
          selectTreeElements(searchMatcher);
          setTreeFilter(searchFilter, false);
          isSettingSelection = false;
        }
        return Status.OK_STATUS;
      }
    };

    searchControl.getSearchText().addFocusListener(new FocusAdapter() {
      public void focusGained(FocusEvent e) {
        // The net effect here is that the field will update 200 ms after
        // the user stops typing.
        updateJob.cancel();
        updateJob.schedule(200);
      }
    });

    searchControl.getSearchText().addModifyListener(e -> {
      updateJob.cancel();
      updateJob.schedule(200);
    });
  }

  protected void setTreeFilter(ViewerFilter filter, boolean force) {
    currentFilter = filter;
    if(filter != null && (force || (treeViewer.getFilters().length > 0 && treeViewer.getFilters()[0] != filter))) {
      treeViewer.addFilter(filter);
    }
  }

  protected void selectListElements(Matcher matcher) {
    DependencyListLabelProvider listLabelProvider = (DependencyListLabelProvider) listViewer.getLabelProvider();
    listLabelProvider.setMatcher(matcher);
    listViewer.refresh();

    if(!matcher.isEmpty() && mavenProject != null) {
      Set<Artifact> projectArtifacts = mavenProject.getArtifacts();
      for(Artifact a : projectArtifacts) {
        if(matcher.isMatchingArtifact(a.getGroupId(), a.getArtifactId())) {
          listViewer.reveal(a);
          break;
        }
      }
    }
  }

  void selectTreeElements(Matcher matcher) {
    DependencyTreeLabelProvider treeLabelProvider = (DependencyTreeLabelProvider) treeViewer.getLabelProvider();
    treeLabelProvider.setMatcher(matcher);
    treeViewer.getTree().setRedraw(false);
    try {
      treeViewer.refresh();
      treeViewer.expandAll();
    } finally {
      treeViewer.getTree().setRedraw(true);
    }

    if(!matcher.isEmpty()) {
      for(DependencyNode node : dependencyNodes) {
        org.eclipse.aether.artifact.Artifact a = node.getDependency().getArtifact();
        if(matcher.isMatchingArtifact(a.getGroupId(), a.getGroupId())) {
          treeViewer.reveal(node);
          break;
        }
      }
    }
  }

  static class DependencyFilter extends ViewerFilter {
    protected Matcher matcher;

    public DependencyFilter(Matcher matcher) {
      this.matcher = matcher;
    }

    public boolean select(Viewer viewer, Object parentElement, Object element) {
      if(matcher != null && !matcher.isEmpty()) {
        // matcher = new TextMatcher(searchControl.getSearchText().getText());
        if(element instanceof Artifact) {
          Artifact a = (Artifact) element;
          return matcher.isMatchingArtifact(a.getGroupId(), a.getArtifactId());

        } else if(element instanceof DependencyNode) {
          DependencyNode node = (DependencyNode) element;
          org.eclipse.aether.artifact.Artifact a = node.getDependency().getArtifact();
          if(matcher.isMatchingArtifact(a.getGroupId(), a.getArtifactId())) {
            return true;
          }

          class ChildMatcher implements DependencyVisitor {
            protected boolean foundMatch = false;

            public boolean visitEnter(DependencyNode node) {
              org.eclipse.aether.artifact.Artifact a = node.getDependency().getArtifact();
              if(matcher.isMatchingArtifact(a.getGroupId(), a.getArtifactId())) {
                foundMatch = true;
                return false;
              }
              return true;
            }

            public boolean visitLeave(DependencyNode node) {
              return true;
            }
          }
          ;

          ChildMatcher childMatcher = new ChildMatcher();
          node.accept(childMatcher);
          return childMatcher.foundMatch;
        }
      }
      return true;
    }

  }

  class ListSelectionFilter extends DependencyFilter implements ISelectionChangedListener, FocusListener {

    public ListSelectionFilter() {
      super(null); // no filter by default
    }

    // ISelectionChangedListener

    public void selectionChanged(SelectionChangedEvent event) {
      if(!isSettingSelection) {
        isSettingSelection = true;
        IStructuredSelection selection = (IStructuredSelection) listViewer.getSelection();
        matcher = new ArtifactMatcher(selection);
        selectTreeElements(matcher);
        setTreeFilter(this, false);
        isSettingSelection = false;
      }
    }

    // FocusListener

    public void focusGained(FocusEvent e) {
      if(hierarchyFilterAction.isChecked()) {
        setTreeFilter(this, false);
//        treeViewer.addFilter(this);
      }
    }

    public void focusLost(FocusEvent e) {
//      treeViewer.removeFilter(this);
      matcher = null;
    }
  }

  final class DependencyTreeContentProvider implements ITreeContentProvider {

    public Object[] getElements(Object input) {
      return getChildren(input);
    }

    public Object[] getChildren(Object element) {
      if(element instanceof DependencyNode) {
        DependencyNode node = (DependencyNode) element;
        List<DependencyNode> children = node.getChildren();
        return children.toArray(new DependencyNode[children.size()]);
      }
      return new Object[0];
    }

    public Object getParent(Object element) {
      return null;
    }

    public boolean hasChildren(Object element) {
      if(element instanceof DependencyNode) {
        DependencyNode node = (DependencyNode) element;
        return !node.getChildren().isEmpty();
      }
      return false;
    }

    public void dispose() {
    }

    public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
    }

  }

  final class DependencyTreeLabelProvider extends LabelProvider implements IColorProvider {

    private boolean showGroupId = false;

    private Matcher matcher = null;

    public void setMatcher(Matcher matcher) {
      this.matcher = matcher;
    }

    public void setShowGroupId(boolean showGroupId) {
      this.showGroupId = showGroupId;
    }

    // IColorProvider

    public Color getForeground(Object element) {
      if(element instanceof DependencyNode) {
        DependencyNode node = (DependencyNode) element;
        String scope = node.getDependency().getScope();
        if(scope != null && !"compile".equals(scope)) { //$NON-NLS-1$
          return Display.getDefault().getSystemColor(SWT.COLOR_DARK_GRAY);
        }
      }
      return null;
    }

    public Color getBackground(Object element) {
      if(matcher != null && !matcher.isEmpty() && element instanceof DependencyNode) {
        org.eclipse.aether.artifact.Artifact a = ((DependencyNode) element).getDependency().getArtifact();
        if(matcher.isMatchingArtifact(a.getGroupId(), a.getArtifactId())) {
          return highlighter.getColor();
        }
      }
      return null;
    }

    // LabelProvider

    @Override
    public String getText(Object element) {
      if(element instanceof DependencyNode) {
        DependencyNode node = (DependencyNode) element;

        org.eclipse.aether.artifact.Artifact a = node.getDependency().getArtifact();

        StringBuilder label = new StringBuilder(128);

        if(showGroupId) {
          label.append(a.getGroupId()).append(" : ");
        }

        label.append(a.getArtifactId()).append(" : ");

        String nodeVersion = a.getBaseVersion();
        label.append(nodeVersion);

        String premanagedVersion = DependencyManagerUtils.getPremanagedVersion(node);

        if(premanagedVersion != null && !premanagedVersion.equals(nodeVersion)) {
          label.append(" (managed from ").append(premanagedVersion).append(")");
        }

        DependencyNode winner = (DependencyNode) node.getData().get(ConflictResolver.NODE_DATA_WINNER);
        if(winner != null) {
          String winnerVersion = winner.getArtifact().getVersion();
          if(!nodeVersion.equals(winnerVersion)) {
            label.append(" (omitted for conflict with ").append(winnerVersion).append(")");
          }
        }

        if(a.getClassifier().length() > 0) {
          label.append(Messages.DependencyTreePage_0).append(a.getClassifier());
        }

        label.append(" [").append(node.getDependency().getScope()).append("]");

        String premanagedScope = DependencyManagerUtils.getPremanagedScope(node);

        if(premanagedScope != null) {
          label.append(" (from ").append(premanagedScope).append(")");
        }

        return label.toString();
      }
      return element.toString();
    }

    @Override
    public Image getImage(Object element) {
      if(element instanceof DependencyNode) {
        DependencyNode node = (DependencyNode) element;
        org.eclipse.aether.artifact.Artifact a = node.getDependency().getArtifact();
        IMavenProjectRegistry projectManager = MavenPlugin.getMavenProjectRegistry();
        IMavenProjectFacade projectFacade = projectManager.getMavenProject(a.getGroupId(), //
            a.getArtifactId(), //
            a.getBaseVersion() == null ? a.getVersion() : a.getBaseVersion());
        return projectFacade == null ? MavenEditorImages.IMG_JAR : MavenEditorImages.IMG_PROJECT;
      }
      return null;
    }
  }

  public class DependencyListLabelProvider extends LabelProvider implements IColorProvider {

    private boolean showGroupId = false;

    private Matcher matcher = null;

    public void setMatcher(Matcher matcher) {
      this.matcher = matcher;
    }

    public void setShowGroupId(boolean showGroupId) {
      this.showGroupId = showGroupId;
    }

    // IColorProvider

    public Color getForeground(Object element) {
      if(element instanceof Artifact) {
        Artifact a = (Artifact) element;
        String scope = a.getScope();
        if(scope != null && !"compile".equals(scope)) { //$NON-NLS-1$
          return Display.getDefault().getSystemColor(SWT.COLOR_DARK_GRAY);
        }
      }
      return null;
    }

    public Color getBackground(Object element) {
      if(matcher != null && !matcher.isEmpty() && element instanceof Artifact) {
        Artifact a = (Artifact) element;
        if(matcher.isMatchingArtifact(a.getGroupId(), a.getArtifactId())) {
          return highlighter.getColor();
        }
      }
      return null;
    }

    // LabelProvider

    @Override
    public String getText(Object element) {
      if(element instanceof Artifact) {
        Artifact a = (Artifact) element;
        StringBuilder label = new StringBuilder(64);

        if(showGroupId) {
          label.append(a.getGroupId()).append(" : ");
        }

        label.append(a.getArtifactId()).append(" : ").append(a.getVersion());

        if(a.hasClassifier()) {
          label.append(" - ").append(a.getClassifier());
        }

        if(a.getScope() != null) {
          label.append(" [").append(a.getScope()).append("]");
        }

        return label.toString();
      }
      return super.getText(element);
    }

    @Override
    public Image getImage(Object element) {
      if(element instanceof Artifact) {
        Artifact a = (Artifact) element;
        IMavenProjectRegistry projectManager = MavenPlugin.getMavenProjectRegistry();
        IMavenProjectFacade projectFacade = projectManager.getMavenProject(a.getGroupId(), //
            a.getArtifactId(), //
            a.getBaseVersion() == null ? a.getVersion() : a.getBaseVersion());
        return projectFacade == null ? MavenEditorImages.IMG_JAR : MavenEditorImages.IMG_PROJECT;
      }
      return null;
    }

  }

  public class DependencyListContentProvider implements IStructuredContentProvider {

    public Object[] getElements(Object input) {
      if(input instanceof MavenProject) {
        MavenProject project = (MavenProject) input;
        List<Artifact> artifacts = new ArrayList<Artifact>();
        ArtifactFilter filter = new org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter(currentClasspath);
        for(Artifact artifact : project.getArtifacts()) {
          if(filter.include(artifact)) {
            artifacts.add(artifact);
          }
        }
        return artifacts.toArray(new Artifact[artifacts.size()]);
      }
      return null;
    }

    public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
    }

    public void dispose() {
    }

  }

  public static class ArtifactMatcher extends Matcher {

    protected final HashSet<String> artifactKeys = new HashSet<String>();

    public ArtifactMatcher(IStructuredSelection selection) {
      for(Iterator<?> it = selection.iterator(); it.hasNext();) {
        addArtifactKey(it.next());
      }
    }

    public boolean isEmpty() {
      return artifactKeys.isEmpty();
    }

    public boolean isMatchingArtifact(String groupId, String artifactId) {
      return artifactKeys.contains(getKey(groupId, artifactId));
    }

    protected void addArtifactKey(Object o) {
      if(o instanceof Artifact) {
        Artifact a = (Artifact) o;
        artifactKeys.add(getKey(a.getGroupId(), a.getArtifactId()));
      }
    }

    protected String getKey(String groupId, String artifactId) {
      return groupId + ":" + artifactId;
    }

  }

  public static class DependencyNodeMatcher extends ArtifactMatcher {

    public DependencyNodeMatcher(IStructuredSelection selection) {
      super(selection);
    }

    @Override
    protected void addArtifactKey(Object o) {
      if(o instanceof DependencyNode) {
        org.eclipse.aether.artifact.Artifact a = ((DependencyNode) o).getDependency().getArtifact();
        artifactKeys.add(getKey(a.getGroupId(), a.getArtifactId()));
      }
    }

  }

  @Override
  public void dispose() {
    MavenPluginActivator.getDefault().getMavenProjectManager().removeMavenProjectChangedListener(this);
    if(highlighter != null) {
      highlighter.dispose();
    }
    super.dispose();
  }

  public void selectDepedency(ArtifactKey artifactKey) {
    if(dataLoadingJob != null && dataLoadingJob.getState() == Job.RUNNING) {
      try {
        dataLoadingJob.join();
      } catch(InterruptedException ex) {
        // ignore
      }
    }

    if(mavenProject != null) {
      Artifact artifact = getArtifact(artifactKey);
      if(artifact != null) {
        listViewer.getTable().setFocus();
        listViewer.setSelection(new StructuredSelection(artifact), true);
      }
    }
  }

  private Artifact getArtifact(ArtifactKey artifactKey) {
    Set<Artifact> artifacts = mavenProject.getArtifacts();
    for(Artifact artifact : artifacts) {
      if(artifactKey.equals(new ArtifactKey(artifact))) {
        return artifact;
      }
    }
    return null;
  }

  public class ClasspathAction extends Action {

    private final String classpath;

    public ClasspathAction(String text, String classpath) {
      super(text, IAction.AS_RADIO_BUTTON);
      this.classpath = classpath;
    }

    public void run() {
      if(isChecked()) {
        currentClasspath = classpath;
        IManagedForm managedForm = DependencyTreePage.this.getManagedForm();
        managedForm.getForm().setText(formatFormTitle());
        loadData(false);
      }
    }
  }

  public void loadData() {
    loadData(true);
  }

  public void mavenProjectChanged(MavenProjectChangedEvent[] events, IProgressMonitor monitor) {
    if(getManagedForm() == null || getManagedForm().getForm() == null)
      return;

    for(int i = 0; i < events.length; i++ ) {
      if(events[i].getSource().equals(((MavenPomEditor) getEditor()).getPomFile())) {
        // file has been changed. need to update graph  
        new UIJob(Messages.DependencyTreePage_job_reloading) {
          public IStatus runInUIThread(IProgressMonitor monitor) {
            loadData();
            FormUtils.setMessage(getManagedForm().getForm(), null, IMessageProvider.WARNING);
            return Status.OK_STATUS;
          }
        }.schedule();
      }
    }
  }

  public void fileChanged() {
    if(getManagedForm() == null || getManagedForm().getForm() == null)
      return;

    new UIJob(Messages.DependencyTreePage_job_reloading) {
      public IStatus runInUIThread(IProgressMonitor monitor) {
        FormUtils.setMessage(getManagedForm().getForm(), Messages.DependencyTreePage_message_updating,
            IMessageProvider.WARNING);
        return Status.OK_STATUS;
      }
    }.schedule();
  }

  /**
   * Holds highlight color, bound to "org.eclipse.search.ui.match.highlight" preference. Updates when preference
   * changes.
   */
  private class Highlighter implements IPropertyChangeListener, IDisposable {

    private static final String HIGHLIGHT_BG_COLOR_NAME = "org.eclipse.search.ui.match.highlight";

    private Color color;

    public Highlighter() {
      initialize();
    }

    public void initialize() {
      dispose();
      JFaceResources.getColorRegistry().addListener(this);
      setColor();
    }

    private void setColor() {
      color = JFaceResources.getColorRegistry().get(HIGHLIGHT_BG_COLOR_NAME);
    }

    public void dispose() {
      JFaceResources.getColorRegistry().removeListener(this);
    }

    public void propertyChange(PropertyChangeEvent event) {
      String property = event.getProperty();
      if(HIGHLIGHT_BG_COLOR_NAME.equals(property)) {
        Display.getDefault().asyncExec(() -> setColor());
      }
    }

    private Color getColor() {
      return color;
    }

  }

}
