/*
 * Copyright (c) 2014, 2015 Eike Stepper (Berlin, Germany) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Eike Stepper - initial API and implementation
 */
package org.eclipse.oomph.p2.internal.ui;

import org.eclipse.oomph.internal.ui.GeneralDragAdapter;
import org.eclipse.oomph.internal.ui.GeneralDropAdapter;
import org.eclipse.oomph.internal.ui.GeneralDropAdapter.DroppedObjectHandler;
import org.eclipse.oomph.internal.ui.OomphTransferDelegate;
import org.eclipse.oomph.p2.P2Exception;
import org.eclipse.oomph.p2.P2Factory;
import org.eclipse.oomph.p2.P2Package;
import org.eclipse.oomph.p2.Repository;
import org.eclipse.oomph.p2.Requirement;
import org.eclipse.oomph.p2.VersionSegment;
import org.eclipse.oomph.p2.core.P2Util;
import org.eclipse.oomph.p2.core.RepositoryProvider;
import org.eclipse.oomph.p2.impl.RequirementImpl;
import org.eclipse.oomph.p2.internal.ui.RepositoryManager.RepositoryManagerListener;
import org.eclipse.oomph.p2.provider.RequirementItemProvider;
import org.eclipse.oomph.ui.SearchField;
import org.eclipse.oomph.ui.SearchField.FilterHandler;
import org.eclipse.oomph.ui.UIUtil;
import org.eclipse.oomph.util.CollectionUtil;
import org.eclipse.oomph.util.ObjectUtil;
import org.eclipse.oomph.util.StringUtil;

import org.eclipse.emf.ecore.EObject;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.runtime.URIUtil;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.variables.IStringVariableManager;
import org.eclipse.core.variables.VariablesPlugin;
import org.eclipse.equinox.p2.core.ProvisionException;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.p2.metadata.IProvidedCapability;
import org.eclipse.equinox.p2.metadata.IRequirement;
import org.eclipse.equinox.p2.metadata.Version;
import org.eclipse.equinox.p2.metadata.VersionRange;
import org.eclipse.equinox.p2.metadata.expression.IMatchExpression;
import org.eclipse.equinox.p2.query.IQueryResult;
import org.eclipse.equinox.p2.query.QueryUtil;
import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository;
import org.eclipse.equinox.p2.repository.metadata.IMetadataRepositoryManager;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.ISelection;
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.StructuredViewer;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CCombo;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.ViewPart;

import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author Eike Stepper
 */
public class RepositoryExplorer extends ViewPart implements FilterHandler
{
  public static final String ID = "org.eclipse.oomph.p2.ui.RepositoryExplorer"; //$NON-NLS-1$

  private static final IDialogSettings SETTINGS = P2UIPlugin.INSTANCE.getDialogSettings(RepositoryExplorer.class.getSimpleName());

  private static final int DND_OPERATIONS = DND.DROP_COPY | DND.DROP_MOVE | DND.DROP_LINK;

  private static final Transfer[] DND_TRANSFERS = OomphTransferDelegate.asTransfers(org.eclipse.oomph.internal.ui.OomphTransferDelegate.DELEGATES)
      .toArray(new Transfer[OomphTransferDelegate.asTransfers(org.eclipse.oomph.internal.ui.OomphTransferDelegate.DELEGATES).size()]);

  private static final String DEFAULT_CAPABILITY_NAMESPACE = IInstallableUnit.NAMESPACE_IU_ID;

  private static final String CURRENT_NAMESPACE_KEY = "currentNamespace";

  private static final String EXPERT_MODE_KEY = "expertMode";

  private static final String CATEGORIZE_ITEMS_KEY = "categorizeItems";

  private static final String VERSION_SEGMENT_KEY = "versionSegment";

  private static final String COMPATIBLE_VERSION_KEY = "compatibleVersion";

  private static final String SOURCE_SUFFIX = ".source";

  private static final String SOURCE_FEATURE_SUFFIX = SOURCE_SUFFIX + Requirement.FEATURE_SUFFIX;

  private static final Object[] NO_ELEMENTS = new Object[0];

  private static final Color WHITE = Display.getCurrent().getSystemColor(SWT.COLOR_WHITE);

  private final LoadJob loadJob = new LoadJob();

  private final AnalyzeJob analyzeJob = new AnalyzeJob();

  private final Mode categoriesMode = new CategoriesMode();

  private final Mode featuresMode = new FeaturesMode();

  private final Mode capabilitiesMode = new CapabilitiesMode();

  private final RepositoryFocusListener repositoryFocusListener = new RepositoryFocusListener();

  private final RepositoryHistoryListener repositoryHistoryListener = new RepositoryHistoryListener();

  private final VersionProvider versionProvider = new VersionProvider();

  private final CollapseAllAction collapseAllAction = new CollapseAllAction();

  private Color gray;

  private Composite container;

  private ComboViewer repositoryViewer;

  private CCombo repositoryCombo;

  private RepositoryProvider.Metadata repositoryProvider;

  private Composite selectorComposite;

  private Composite itemsComposite;

  private StructuredViewer itemsViewer;

  private CategoryItem itemsViewerInput;

  private TableViewer versionsViewer;

  private String currentNamespace;

  private boolean expertMode;

  private boolean categorizeItems;

  private boolean compatibleVersion;

  private Mode mode;

  private IQueryResult<IInstallableUnit> installableUnits;

  private String filter;

  public RepositoryExplorer()
  {
    currentNamespace = SETTINGS.get(CURRENT_NAMESPACE_KEY);
    if (currentNamespace == null)
    {
      currentNamespace = DEFAULT_CAPABILITY_NAMESPACE;
    }

    expertMode = SETTINGS.getBoolean(EXPERT_MODE_KEY);

    String value = SETTINGS.get(CATEGORIZE_ITEMS_KEY);
    if (value == null || value.length() == 0)
    {
      categorizeItems = true;
    }
    else
    {
      categorizeItems = "true".equals(value);
    }

    compatibleVersion = SETTINGS.getBoolean(COMPATIBLE_VERSION_KEY);
  }

  @Override
  public void dispose()
  {
    gray.dispose();
    gray = null;

    disposeRepositoryProvider();
    super.dispose();
  }

  private void disposeRepositoryProvider()
  {
    if (repositoryProvider != null)
    {
      repositoryProvider.dispose();
      repositoryProvider = null;
    }
  }

  @Override
  public void setFocus()
  {
    if (RepositoryManager.INSTANCE.getActiveRepository() != null)
    {
      repositoryCombo.setFocus();
    }
  }

  private void updateMode()
  {
    Mode mode = expertMode ? capabilitiesMode : categorizeItems ? categoriesMode : featuresMode;
    if (this.mode != mode)
    {
      this.mode = mode;

      GridLayout selectorLayout = new GridLayout();
      selectorLayout.marginWidth = 0;
      selectorLayout.marginHeight = 0;

      selectorComposite.setLayout(selectorLayout);
      mode.fillSelector(selectorComposite);
      selectorComposite.layout();
      selectorComposite.getParent().layout();

      mode.fillItems(itemsComposite);
      itemsComposite.layout();

      itemsViewer.addSelectionChangedListener(new ISelectionChangedListener()
      {
        public void selectionChanged(SelectionChangedEvent event)
        {
          IStructuredSelection selection = (IStructuredSelection)itemsViewer.getSelection();
          if (selection.size() == 1)
          {
            versionsViewer.setInput(selection.getFirstElement());
          }
          else
          {
            versionsViewer.setInput(null);
          }
        }
      });

      analyzeJob.reschedule();
      collapseAllAction.updateEnablement();
    }
  }

  private void setItems(Item... items)
  {
    if (!container.isDisposed())
    {
      versionsViewer.setInput(null);

      itemsViewerInput = new CategoryItem();
      itemsViewerInput.setChildren(items);
      itemsViewer.setInput(itemsViewerInput);

      if (itemsViewer instanceof TreeViewer && filter != null)
      {
        TreeViewer treeViewer = (TreeViewer)itemsViewer;
        treeViewer.expandAll();
      }
    }
  }

  private boolean isFiltered(String string)
  {
    return filter == null || string == null || string.toLowerCase().contains(filter);
  }

  public void handleFilter(String filter)
  {
    if (filter == null || filter.length() == 0)
    {
      this.filter = null;
    }
    else
    {
      this.filter = filter.toLowerCase();
    }

    analyzeJob.reschedule();
  }

  @Override
  public void createPartControl(Composite parent)
  {
    final Display display = parent.getDisplay();
    gray = new Color(display, 75, 75, 75);

    container = new Composite(parent, SWT.NONE);
    container.setBackground(WHITE);
    container.setLayout(new GridLayout(1, false));

    createRepositoriesArea(container);
    createItemsArea(container);
    createVersionsArea(container);

    updateMode();

    String activeRepository = RepositoryManager.INSTANCE.getActiveRepository();
    if (activeRepository == null)
    {
      // Force hint to be shown.
      repositoryFocusListener.focusLost(null);
    }
    else
    {
      repositoryCombo.setText(activeRepository);
      triggerLoad(activeRepository);
    }

    hookActions();
  }

  private static CCombo createCombo(Composite parent, int style, boolean grabExcessHorizontalSpace)
  {
    CCombo combo = new CCombo(parent, style);
    GridData layoutData = new GridData(SWT.FILL, SWT.FILL, grabExcessHorizontalSpace, false);

    int increaseHeight = 0;
    String ws = Platform.getWS();
    if (Platform.WS_COCOA.equals(ws))
    {
      increaseHeight = 7;
    }
    else if (Platform.WS_GTK.equals(ws))
    {
      increaseHeight = 9;
    }

    if (increaseHeight != 0)
    {
      FontData[] fontData = combo.getFont().getFontData();
      layoutData.heightHint = fontData[0].getHeight() + increaseHeight;
    }

    combo.setLayoutData(layoutData);
    return combo;
  }

  private void createRepositoriesArea(Composite container)
  {
    repositoryCombo = createCombo(container, SWT.BORDER, true);
    repositoryCombo.setToolTipText("Repository location (type a URL, drop a repository or pick from the drop down history)");
    repositoryCombo.addFocusListener(repositoryFocusListener);
    repositoryCombo.addKeyListener(repositoryHistoryListener);

    repositoryViewer = new ComboViewer(repositoryCombo);
    repositoryViewer.setContentProvider(new RepositoryContentProvider());
    repositoryViewer.setLabelProvider(new LabelProvider());
    repositoryViewer.setInput(RepositoryManager.INSTANCE);
    repositoryViewer.addSelectionChangedListener(repositoryHistoryListener);

    repositoryViewer.addDropSupport(DND_OPERATIONS, DND_TRANSFERS, new GeneralDropAdapter(repositoryViewer, P2Factory.eINSTANCE.createRepositoryList(),
        P2Package.Literals.REPOSITORY_LIST__REPOSITORIES, new DroppedObjectHandler()
        {
          public void handleDroppedObject(Object object) throws Exception
          {
            if (object instanceof Repository)
            {
              Repository repository = (Repository)object;
              String url = repository.getURL();
              if (!StringUtil.isEmpty(url))
              {
                activateAndLoadRepository(url);
              }
            }
          }
        }));
  }

  private void createItemsArea(Composite parent)
  {
    GridLayout containerLayout = new GridLayout(2, false);
    containerLayout.marginWidth = 0;
    containerLayout.marginHeight = 0;

    Composite container = new Composite(parent, SWT.NONE);
    container.setBackground(WHITE);
    container.setLayout(containerLayout);
    container.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

    SearchField searchField = new SearchField(container, this)
    {
      @Override
      protected void finishFilter()
      {
        itemsViewer.getControl().setFocus();
        selectFirstLeaf(itemsViewerInput);
      }

      private void selectFirstLeaf(CategoryItem category)
      {
        Item[] children = category.getChildren();
        if (children != null && children.length != 0)
        {
          Item firstChild = children[0];
          if (firstChild instanceof CategoryItem)
          {
            CategoryItem firstCategory = (CategoryItem)firstChild;
            selectFirstLeaf(firstCategory);
          }
          else
          {
            itemsViewer.setSelection(new StructuredSelection(firstChild));
          }
        }
      }
    };

    searchField.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));

    selectorComposite = new Composite(container, SWT.NONE);
    selectorComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
    selectorComposite.setBackground(WHITE);

    itemsComposite = new Composite(container, SWT.NONE);
    itemsComposite.setBackground(WHITE);
    itemsComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
    itemsComposite.setLayout(new FillLayout());
  }

  private void createVersionsArea(Composite container)
  {
    Composite versionsComposite = new Composite(container, SWT.NONE);
    versionsComposite.setBackground(WHITE);
    GridLayout gl_versionsComposite = new GridLayout(2, false);
    gl_versionsComposite.marginWidth = 0;
    gl_versionsComposite.marginHeight = 0;
    versionsComposite.setLayout(gl_versionsComposite);
    versionsComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));

    versionsViewer = new TableViewer(versionsComposite, SWT.BORDER);
    versionsViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1));
    versionsViewer.setContentProvider(versionProvider);
    versionsViewer.setLabelProvider(versionProvider);
    addDragSupport(versionsViewer);

    Composite versionsGroup = new Composite(versionsComposite, SWT.NONE);
    versionsGroup.setBackground(WHITE);
    versionsGroup.setLayout(new GridLayout(1, false));
    versionsGroup.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false));

    final Button compatibleButton = new Button(versionsGroup, SWT.CHECK);
    compatibleButton.setText("Compatible");
    compatibleButton.setToolTipText("Show compatible versions");
    compatibleButton.setSelection(compatibleVersion);

    final Button majorButton = addVersionSegmentButton(versionsGroup, "Major", "Show major versions", VersionSegment.MAJOR);
    final Button minorButton = addVersionSegmentButton(versionsGroup, "Minor", "Show minor versions", VersionSegment.MINOR);
    addVersionSegmentButton(versionsGroup, "Micro", "Show micro versions", VersionSegment.MICRO);
    addVersionSegmentButton(versionsGroup, "Qualifier", "Show qualified versions", VersionSegment.QUALIFIER);

    majorButton.setEnabled(!compatibleVersion);
    compatibleButton.addSelectionListener(new SelectionAdapter()
    {
      @Override
      public void widgetSelected(SelectionEvent e)
      {
        boolean compatible = compatibleButton.getSelection();
        if (compatibleVersion != compatible)
        {
          compatibleVersion = compatible;
          SETTINGS.put(COMPATIBLE_VERSION_KEY, compatibleVersion);

          majorButton.setEnabled(!compatible);

          if (compatible && versionProvider.getVersionSegment() == VersionSegment.MAJOR)
          {
            majorButton.setSelection(false);
            minorButton.setSelection(true);
            versionProvider.setVersionSegment(VersionSegment.MINOR);
          }
        }
      }
    });
  }

  private Button addVersionSegmentButton(Composite parent, String text, String toolTip, final VersionSegment versionSegment)
  {
    Button button = new Button(parent, SWT.RADIO);
    button.setText(text);
    button.setToolTipText(toolTip);
    button.addSelectionListener(new SelectionAdapter()
    {
      @Override
      public void widgetSelected(SelectionEvent e)
      {
        versionProvider.setVersionSegment(versionSegment);
      }
    });

    if (versionSegment == versionProvider.getVersionSegment())
    {
      button.setSelection(true);
    }

    return button;
  }

  private void hookActions()
  {
    IActionBars actionBars = getViewSite().getActionBars();

    IToolBarManager toolbarManager = actionBars.getToolBarManager();
    toolbarManager.add(new Separator("additions"));
    toolbarManager.add(collapseAllAction);

    toolbarManager.add(new Action("Refresh", P2UIPlugin.INSTANCE.getImageDescriptor("refresh"))
    {
      {
        setToolTipText("Reload the active repository and refresh the tree");
      }

      @Override
      public void run()
      {
        String activeRepository = RepositoryManager.INSTANCE.getActiveRepository();
        if (activeRepository != null)
        {
          disposeRepositoryProvider();
          triggerLoad(activeRepository);
        }
      }
    });

    toolbarManager.add(new Separator("modes"));
    toolbarManager.add(new Action("Expert Mode", IAction.AS_CHECK_BOX)
    {
      {
        setImageDescriptor(P2UIPlugin.INSTANCE.getImageDescriptor("obj16/capability"));
        setChecked(expertMode);
      }

      @Override
      public void run()
      {
        expertMode = isChecked();
        SETTINGS.put(EXPERT_MODE_KEY, expertMode);
        updateMode();
      }
    });

    toolbarManager.add(new Separator("end"));
  }

  private void activateAndLoadRepository(String repository)
  {
    if (RepositoryManager.INSTANCE.setActiveRepository(repository))
    {
      triggerLoad(repository);
    }
  }

  private void triggerLoad(String repository)
  {
    try
    {
      IStringVariableManager manager = VariablesPlugin.getDefault().getStringVariableManager();
      repository = manager.performStringSubstitution(repository);
    }
    catch (Exception ex)
    {
      //$FALL-THROUGH$
    }

    URI location = null;

    try
    {
      location = new URI(repository);
    }
    catch (URISyntaxException ex)
    {
      File folder = new File(repository);
      if (folder.isDirectory())
      {
        location = folder.toURI();
      }
    }

    if (location != null)
    {
      loadJob.reschedule(location);
    }
  }

  private void addDragSupport(StructuredViewer viewer)
  {
    viewer.addDragSupport(DND_OPERATIONS, DND_TRANSFERS, new GeneralDragAdapter(viewer, new GeneralDragAdapter.DraggedObjectsFactory()
    {
      public List<EObject> createDraggedObjects(ISelection selection) throws Exception
      {
        List<EObject> result = new ArrayList<EObject>();

        IStructuredSelection ssel = (IStructuredSelection)selection;
        for (Iterator<?> it = ssel.iterator(); it.hasNext();)
        {
          Object element = it.next();

          VersionRange versionRange = VersionRange.emptyRange;
          String filter = null;

          if (element instanceof VersionProvider.ItemVersion)
          {
            VersionProvider.ItemVersion itemVersion = (VersionProvider.ItemVersion)element;
            Version version = itemVersion.getVersion();

            VersionSegment versionSegment = versionProvider.getVersionSegment();
            versionRange = P2Factory.eINSTANCE.createVersionRange(version, versionSegment, compatibleVersion);

            filter = RequirementImpl.formatMatchExpression(itemVersion.getFilter());

            element = ((IStructuredSelection)itemsViewer.getSelection()).getFirstElement();
          }

          if (element instanceof Item)
          {
            Item item = (Item)element;

            String namespace = item.getNamespace();
            if (namespace != null)
            {
              if (filter == null && item instanceof VersionedItem)
              {
                VersionedItem versionedItem = (VersionedItem)item;

                for (IMatchExpression<IInstallableUnit> matchExpression : versionedItem.getVersions().values())
                {
                  String string = RequirementImpl.formatMatchExpression(matchExpression);
                  if (filter == null || filter.equals(string))
                  {
                    filter = string;
                  }
                  else
                  {
                    filter = null;
                    break;
                  }
                }
              }

              Requirement requirement = P2Factory.eINSTANCE.createRequirement();
              requirement.setNamespace(namespace);
              requirement.setName(item.getName());
              requirement.setVersionRange(versionRange);
              requirement.setFilter(filter);
              result.add(requirement);
            }
          }
        }

        return result;
      }
    }));
  }

  private static String[] sortStrings(Collection<String> c)
  {
    String[] array = c.toArray(new String[c.size()]);
    Arrays.sort(array);
    return array;
  }

  private static String[] getMinimalFlavors(final Set<String> flavors)
  {
    String[] flavorIDs = sortStrings(flavors);
    int start = 0;

    while (start < flavorIDs.length)
    {
      boolean changed = false;
      for (int i = start + 1; i < flavorIDs.length; i++)
      {
        String flavorID = flavorIDs[i];
        if (flavorID.startsWith(flavorIDs[start]))
        {
          flavors.remove(flavorID);
          changed = true;
        }
      }

      if (changed)
      {
        flavorIDs = sortStrings(flavors);
      }

      ++start;
    }

    return flavorIDs;
  }

  private static boolean isCategory(IInstallableUnit iu)
  {
    return "true".equalsIgnoreCase(iu.getProperty(QueryUtil.PROP_TYPE_CATEGORY));
  }

  private static boolean isFeature(IInstallableUnit iu)
  {
    return iu.getId().endsWith(Requirement.FEATURE_SUFFIX);
  }

  public static boolean explore(String repository)
  {
    IWorkbenchWindow window = UIUtil.WORKBENCH.getActiveWorkbenchWindow();
    if (window != null)
    {
      IWorkbenchPage page = window.getActivePage();
      if (page != null)
      {
        IViewPart view = page.findView(ID);
        if (view == null)
        {
          try
          {
            view = page.showView(ID);
          }
          catch (PartInitException ex)
          {
            P2UIPlugin.INSTANCE.log(ex);
          }
        }

        if (view instanceof RepositoryExplorer)
        {
          RepositoryExplorer explorer = (RepositoryExplorer)view;
          explorer.activateAndLoadRepository(repository);
          return true;
        }
      }
    }

    return false;
  }

  /**
   * @author Eike Stepper
   */
  private final class CollapseAllAction extends Action
  {
    public CollapseAllAction()
    {
      super("Collapse All", P2UIPlugin.INSTANCE.getImageDescriptor("collapse-all"));
      setToolTipText("Collapse all tree items");
      updateEnablement();
    }

    public void updateEnablement()
    {
      setEnabled(itemsViewer instanceof TreeViewer);
    }

    @Override
    public void run()
    {
      if (itemsViewer instanceof TreeViewer)
      {
        TreeViewer treeViewer = (TreeViewer)itemsViewer;
        treeViewer.collapseAll();
      }
    }
  }

  /**
   * @author Eike Stepper
   */
  private abstract class SafeJob extends Job
  {
    public SafeJob(String name)
    {
      super(name);
    }

    @Override
    protected final IStatus run(IProgressMonitor monitor)
    {
      try
      {
        doSafe(monitor);
        return Status.OK_STATUS;
      }
      catch (OperationCanceledException ex)
      {
        return Status.CANCEL_STATUS;
      }
      catch (Exception ex)
      {
        if (ex instanceof P2Exception)
        {
          Throwable cause = ex.getCause();
          if (cause instanceof CoreException)
          {
            ex = (CoreException)cause;
          }
        }

        final IStatus status = P2UIPlugin.INSTANCE.getStatus(ex);
        UIUtil.asyncExec(new Runnable()
        {
          public void run()
          {
            setItems(new ErrorItem(status));
          }
        });

        return Status.OK_STATUS;
      }
      catch (Throwable t)
      {
        return P2UIPlugin.INSTANCE.getStatus(t);
      }
    }

    protected abstract void doSafe(IProgressMonitor monitor) throws Throwable;
  }

  /**
   * @author Eike Stepper
   */
  private final class LoadJob extends SafeJob
  {
    private URI location;

    public LoadJob()
    {
      super("Loading repository");
    }

    public void reschedule(URI location)
    {
      this.location = location;
      setItems(new LoadingItem(location));

      cancel();
      schedule();
    }

    @Override
    @SuppressWarnings("restriction")
    protected void doSafe(IProgressMonitor monitor) throws Throwable
    {
      analyzeJob.cancel();
      installableUnits = null;

      IMetadataRepositoryManager repositoryManager = P2Util.getAgentManager().getCurrentAgent().getMetadataRepositoryManager();
      if (repositoryProvider == null || !repositoryProvider.getLocation().equals(location))
      {
        disposeRepositoryProvider();
        repositoryProvider = new RepositoryProvider.Metadata(repositoryManager, location);
      }

      SubMonitor progress = SubMonitor.convert(monitor, 101);

      IMetadataRepository repository = repositoryProvider.getRepository(progress.newChild(100));

      if (repository instanceof org.eclipse.equinox.internal.p2.metadata.repository.CompositeMetadataRepository)
      {
        org.eclipse.equinox.internal.p2.metadata.repository.CompositeMetadataRepository compositeRepository = (org.eclipse.equinox.internal.p2.metadata.repository.CompositeMetadataRepository)repository;
        org.eclipse.equinox.internal.p2.persistence.CompositeRepositoryState state = compositeRepository.toState();
        URI[] children = state.getChildren();

        final List<Item> errors = new ArrayList<Item>();
        Set<String> messages = new HashSet<String>();

        for (URI child : children)
        {
          try
          {
            URI absolute = URIUtil.makeAbsolute(child, location);
            if (repositoryManager.loadRepository(absolute, null) == null)
            {
              throw new ProvisionException("No repository found at " + absolute + ".");
            }
          }
          catch (Exception ex)
          {
            IStatus status = P2UIPlugin.INSTANCE.getStatus(ex);
            if (messages.add(status.getMessage()))
            {
              errors.add(new ErrorItem(status));
            }
          }
        }

        if (!errors.isEmpty())
        {
          UIUtil.asyncExec(new Runnable()
          {
            public void run()
            {
              setItems(errors.toArray(new Item[errors.size()]));
            }
          });

          return;
        }
      }

      installableUnits = repository.query(QueryUtil.createIUAnyQuery(), progress.newChild(1));
      analyzeJob.reschedule();
    }
  }

  /**
   * @author Eike Stepper
   */
  private final class AnalyzeJob extends SafeJob
  {
    public AnalyzeJob()
    {
      super("Analyzing repository");
    }

    public void reschedule()
    {
      cancel();

      if (installableUnits != null)
      {
        schedule();
      }
    }

    @Override
    protected void doSafe(IProgressMonitor monitor) throws Throwable
    {
      mode.analyzeInstallableUnits(monitor);
    }
  }

  /**
   * @author Eike Stepper
   */
  private abstract class Mode
  {
    protected final void disposeChildren(Composite parent)
    {
      for (Control child : parent.getChildren())
      {
        child.dispose();
      }
    }

    protected final void fillCategorySelector(Composite parent)
    {
      Control[] children = parent.getChildren();
      if (children.length == 1 && children[0] instanceof Button)
      {
        ((Button)children[0]).setSelection(categorizeItems);
        return;
      }

      disposeChildren(parent);

      final Button button = new Button(parent, SWT.CHECK);
      button.setText("Group items by category");
      button.setToolTipText("Whether to show items in categories or in a complete list");
      button.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
      button.setSelection(categorizeItems);
      button.addSelectionListener(new SelectionAdapter()
      {
        @Override
        public void widgetSelected(SelectionEvent e)
        {
          categorizeItems = button.getSelection();
          SETTINGS.put(CATEGORIZE_ITEMS_KEY, categorizeItems);

          updateMode();
        }
      });
    }

    public abstract void fillSelector(Composite parent);

    public abstract void fillItems(Composite parent);

    public abstract void analyzeInstallableUnits(IProgressMonitor monitor);
  }

  /**
   * @author Eike Stepper
   */
  private final class CategoriesMode extends Mode
  {
    @Override
    public void fillSelector(Composite parent)
    {
      fillCategorySelector(parent);
    }

    @Override
    public void fillItems(Composite parent)
    {
      disposeChildren(parent);

      TreeViewer categoriesViewer = new TreeViewer(parent, SWT.BORDER | SWT.MULTI);
      categoriesViewer.setUseHashlookup(true);
      categoriesViewer.setContentProvider(new ItemContentProvider());
      categoriesViewer.setLabelProvider(new ItemLabelProvider());
      addDragSupport(categoriesViewer);

      itemsViewer = categoriesViewer;
    }

    @SuppressWarnings("restriction")
    @Override
    public void analyzeInstallableUnits(IProgressMonitor monitor)
    {
      // IU.id -> value
      Map<String, String> names = new HashMap<String, String>();
      Map<String, Set<IInstallableUnit>> ius = new HashMap<String, Set<IInstallableUnit>>();
      Map<String, Set<IRequirement>> categories = new HashMap<String, Set<IRequirement>>();

      for (IInstallableUnit iu : installableUnits)
      {
        P2UIPlugin.checkCancelation(monitor);
        String id = iu.getId();

        names.put(id, P2Util.getName(iu));
        CollectionUtil.add(ius, id, iu);

        if (isCategory(iu))
        {
          CollectionUtil.addAll(categories, id, iu.getRequirements());
        }
      }

      Set<String> rootIDs = new HashSet<String>();

      for (String categoryID : categories.keySet())
      {
        P2UIPlugin.checkCancelation(monitor);
        rootIDs.add(categoryID);
      }

      for (Set<IRequirement> requirements : categories.values())
      {
        for (IRequirement requirement : requirements)
        {
          P2UIPlugin.checkCancelation(monitor);

          if (requirement instanceof org.eclipse.equinox.internal.p2.metadata.IRequiredCapability)
          {
            org.eclipse.equinox.internal.p2.metadata.IRequiredCapability requiredCapability = (org.eclipse.equinox.internal.p2.metadata.IRequiredCapability)requirement;
            if (IInstallableUnit.NAMESPACE_IU_ID.equals(requiredCapability.getNamespace()))
            {
              rootIDs.remove(requiredCapability.getName());
            }
          }
        }
      }

      Set<CategoryItem> rootCategories = new HashSet<CategoryItem>();
      for (String rootID : rootIDs)
      {
        P2UIPlugin.checkCancelation(monitor);

        CategoryItem rootCategory = analyzeCategory(names, ius, categories, rootID, monitor);
        if (rootCategory != null)
        {
          rootCategories.add(rootCategory);
        }
      }

      final CategoryItem[] roots = rootCategories.toArray(new CategoryItem[rootCategories.size()]);
      UIUtil.asyncExec(new Runnable()
      {
        public void run()
        {
          setItems(roots);
        }
      });
    }

    @SuppressWarnings("restriction")
    private CategoryItem analyzeCategory(Map<String, String> names, Map<String, Set<IInstallableUnit>> ius, Map<String, Set<IRequirement>> categories,
        String categoryID, IProgressMonitor monitor)
    {
      Map<String, Item> children = new HashMap<String, Item>();
      Map<Item, Map<Version, IMatchExpression<IInstallableUnit>>> versions = new HashMap<Item, Map<Version, IMatchExpression<IInstallableUnit>>>();

      for (IRequirement requirement : categories.get(categoryID))
      {
        P2UIPlugin.checkCancelation(monitor);

        if (requirement instanceof org.eclipse.equinox.internal.p2.metadata.IRequiredCapability)
        {
          org.eclipse.equinox.internal.p2.metadata.IRequiredCapability requiredCapability = (org.eclipse.equinox.internal.p2.metadata.IRequiredCapability)requirement;
          if (IInstallableUnit.NAMESPACE_IU_ID.equals(requiredCapability.getNamespace()))
          {
            String requiredID = requiredCapability.getName();
            if (categories.containsKey(requiredID))
            {
              CategoryItem child = analyzeCategory(names, ius, categories, requiredID, monitor);
              if (child != null)
              {
                children.put(requiredID, child);
              }
            }
            else
            {
              VersionRange range = requiredCapability.getRange();
              Item child = children.get(requiredID);

              Set<IInstallableUnit> set = ius.get(requiredID);
              for (IInstallableUnit iu : set)
              {
                P2UIPlugin.checkCancelation(monitor);
                Version version = iu.getVersion();

                if (range.isIncluded(version))
                {
                  if (child == null)
                  {
                    String name = names.get(requiredID);
                    if (isFiltered(name))
                    {
                      if (isFeature(iu))
                      {
                        if (requiredID.endsWith(SOURCE_FEATURE_SUFFIX))
                        {
                          String mainID = requiredID.substring(0, requiredID.length() - SOURCE_FEATURE_SUFFIX.length()) + Requirement.FEATURE_SUFFIX;
                          String mainName = names.get(mainID);

                          if (ObjectUtil.equals(name, mainName))
                          {
                            name += " (Source)";
                          }
                        }

                        child = new FeatureItem(requiredID);
                      }
                      else
                      {
                        if (requiredID.endsWith(SOURCE_SUFFIX))
                        {
                          String mainID = requiredID.substring(0, requiredID.length() - SOURCE_SUFFIX.length());
                          String mainName = names.get(mainID);

                          if (ObjectUtil.equals(name, mainName))
                          {
                            name += " (Source)";
                          }
                        }

                        child = new PluginItem(requiredID);
                      }

                      child.setLabel(name);
                      children.put(requiredID, child);
                    }
                  }

                  if (child != null)
                  {
                    IMatchExpression<IInstallableUnit> matchExpression = iu.getFilter();

                    Map<Version, IMatchExpression<IInstallableUnit>> map = versions.get(child);
                    if (map == null)
                    {
                      map = new HashMap<Version, IMatchExpression<IInstallableUnit>>();
                      versions.put(child, map);
                    }

                    map.put(version, matchExpression);
                  }
                }
              }
            }
          }
        }
      }

      for (Map.Entry<Item, Map<Version, IMatchExpression<IInstallableUnit>>> entry : versions.entrySet())
      {
        P2UIPlugin.checkCancelation(monitor);

        Item child = entry.getKey();
        if (child instanceof VersionedItem)
        {
          VersionedItem versionedItem = (VersionedItem)child;
          versionedItem.setVersions(entry.getValue());
        }
      }

      if (children.isEmpty())
      {
        return null;
      }

      CategoryItem categoryItem = new CategoryItem();
      categoryItem.setLabel(names.get(categoryID));
      categoryItem.setChildren(children.values().toArray(new Item[children.size()]));
      return categoryItem;
    }
  }

  /**
   * @author Eike Stepper
   */
  private final class FeaturesMode extends Mode
  {
    @Override
    public void fillSelector(Composite parent)
    {
      fillCategorySelector(parent);
    }

    @Override
    public void fillItems(Composite parent)
    {
      disposeChildren(parent);

      TableViewer featuresViewer = new TableViewer(parent, SWT.BORDER | SWT.MULTI | SWT.VIRTUAL);
      featuresViewer.setUseHashlookup(true);
      featuresViewer.setContentProvider(new ItemContentProvider());
      featuresViewer.setLabelProvider(new ItemLabelProvider());
      addDragSupport(featuresViewer);

      itemsViewer = featuresViewer;
    }

    @Override
    public void analyzeInstallableUnits(IProgressMonitor monitor)
    {
      Map<String, String> names = new HashMap<String, String>();
      Map<String, Map<Version, IMatchExpression<IInstallableUnit>>> versions = new HashMap<String, Map<Version, IMatchExpression<IInstallableUnit>>>();

      for (IInstallableUnit iu : installableUnits)
      {
        P2UIPlugin.checkCancelation(monitor);
        String id = iu.getId();

        if (id.endsWith(Requirement.FEATURE_SUFFIX) && !id.endsWith(SOURCE_FEATURE_SUFFIX))
        {
          String name = P2Util.getName(iu);
          if (isFiltered(name))
          {
            names.put(id, name);

            Version version = iu.getVersion();
            IMatchExpression<IInstallableUnit> filter = iu.getFilter();

            Map<Version, IMatchExpression<IInstallableUnit>> map = versions.get(id);
            if (map == null)
            {
              map = new HashMap<Version, IMatchExpression<IInstallableUnit>>();
              versions.put(id, map);
            }

            map.put(version, filter);
          }
        }
      }

      final FeatureItem[] featureItems = new FeatureItem[versions.size()];
      Iterator<String> iterator = versions.keySet().iterator();

      for (int i = 0; i < featureItems.length; i++)
      {
        P2UIPlugin.checkCancelation(monitor);
        String id = iterator.next();
        Map<Version, IMatchExpression<IInstallableUnit>> map = versions.get(id);

        FeatureItem featureItem = new FeatureItem(id);
        featureItem.setVersions(map);
        featureItem.setLabel(names.get(id));
        featureItems[i] = featureItem;
      }

      UIUtil.asyncExec(new Runnable()
      {
        public void run()
        {
          setItems(featureItems);
        }
      });
    }
  }

  /**
   * @author Eike Stepper
   */
  private final class CapabilitiesMode extends Mode
  {
    private ComboViewer namespaceViewer;

    @Override
    public void fillSelector(Composite parent)
    {
      disposeChildren(parent);

      CCombo namespaceCombo =
      // new CCombo(parent, SWT.BORDER | SWT.READ_ONLY | SWT.FLAT);
      createCombo(parent, SWT.BORDER | SWT.READ_ONLY | SWT.FLAT, false);
      namespaceCombo.setToolTipText("Select the namespace of the capabilities to show");

      namespaceViewer = new ComboViewer(namespaceCombo);
      namespaceViewer.setSorter(new ViewerSorter());
      namespaceViewer.setContentProvider(new ArrayContentProvider());
      namespaceViewer.setLabelProvider(new LabelProvider());
      namespaceViewer.setInput(new String[] { currentNamespace });
      namespaceViewer.addSelectionChangedListener(new ISelectionChangedListener()
      {
        public void selectionChanged(SelectionChangedEvent event)
        {
          IStructuredSelection selection = (IStructuredSelection)namespaceViewer.getSelection();
          String newNamespace = (String)selection.getFirstElement();
          if (!ObjectUtil.equals(newNamespace, currentNamespace))
          {
            SETTINGS.put(CURRENT_NAMESPACE_KEY, newNamespace);
            currentNamespace = newNamespace;
            analyzeJob.reschedule();
          }
        }
      });

      namespaceViewer.setSelection(new StructuredSelection(currentNamespace));
    }

    @Override
    public void fillItems(Composite parent)
    {
      disposeChildren(parent);

      TableViewer capabilitiesViewer = new TableViewer(parent, SWT.BORDER | SWT.MULTI | SWT.VIRTUAL);
      capabilitiesViewer.setUseHashlookup(true);
      capabilitiesViewer.setContentProvider(new ItemContentProvider());
      capabilitiesViewer.setLabelProvider(new ItemLabelProvider());
      addDragSupport(capabilitiesViewer);

      itemsViewer = capabilitiesViewer;
    }

    @Override
    public void analyzeInstallableUnits(IProgressMonitor monitor)
    {
      final Set<String> flavors = new HashSet<String>();
      final Set<String> namespaces = new HashSet<String>();
      Map<String, Set<Version>> versions = new HashMap<String, Set<Version>>();

      for (IInstallableUnit iu : installableUnits)
      {
        for (IProvidedCapability capability : iu.getProvidedCapabilities())
        {
          P2UIPlugin.checkCancelation(monitor);

          String namespace = capability.getNamespace();
          String name = capability.getName();

          if ("org.eclipse.equinox.p2.flavor".equals(namespace))
          {
            flavors.add(name);
          }
          else if (!"A.PDE.Target.Platform".equalsIgnoreCase(namespace))
          {
            namespaces.add(namespace);
          }

          if (ObjectUtil.equals(namespace, currentNamespace) && isFiltered(name))
          {
            Version version = capability.getVersion();
            if (version != null && !Version.emptyVersion.equals(version))
            {
              CollectionUtil.add(versions, name, version);
            }
          }
        }
      }

      String[] flavorIDs = getMinimalFlavors(flavors);
      for (Iterator<String> it = namespaces.iterator(); it.hasNext();)
      {
        String namespace = it.next();
        for (int i = 0; i < flavorIDs.length; i++)
        {
          String flavor = flavorIDs[i];
          if (namespace.startsWith(flavor))
          {
            it.remove();
            break;
          }
        }
      }

      if (!namespaces.contains(currentNamespace))
      {
        String newCurrentNamespace = null;
        if (namespaces.contains(DEFAULT_CAPABILITY_NAMESPACE))
        {
          newCurrentNamespace = DEFAULT_CAPABILITY_NAMESPACE;
        }
        else if (!namespaces.isEmpty())
        {
          newCurrentNamespace = namespaces.iterator().next();
        }

        if (newCurrentNamespace != null)
        {
          currentNamespace = newCurrentNamespace;
          analyzeInstallableUnits(monitor);
          return;
        }
      }

      final CapabilityItem[] capabilityItems = new CapabilityItem[versions.size()];
      Iterator<String> iterator = versions.keySet().iterator();

      for (int i = 0; i < capabilityItems.length; i++)
      {
        String id = iterator.next();

        CapabilityItem capabilityItem = new CapabilityItem();
        capabilityItem.setVersions(versions.get(id));
        capabilityItem.setNamespace(currentNamespace);
        capabilityItem.setLabel(id);
        capabilityItems[i] = capabilityItem;
      }

      UIUtil.asyncExec(new Runnable()
      {
        public void run()
        {
          if (!container.isDisposed())
          {
            setItems(capabilityItems);

            namespaceViewer.setInput(namespaces);
            namespaceViewer.getCCombo().pack();
            selectorComposite.getParent().layout();

            UIUtil.asyncExec(new Runnable()
            {
              public void run()
              {
                if (!container.isDisposed() && currentNamespace != null)
                {
                  namespaceViewer.setSelection(new StructuredSelection(currentNamespace));
                }
              }
            });
          }
        }
      });
    }
  }

  /**
   * @author Eike Stepper
   */
  private final class RepositoryFocusListener implements FocusListener
  {
    private Color originalForeground;

    public void focusGained(FocusEvent e)
    {
      if (originalForeground != null)
      {
        repositoryCombo.setText("");
        repositoryCombo.setForeground(originalForeground);
        originalForeground = null;
      }
    }

    public void focusLost(FocusEvent e)
    {
      String activeRepository = RepositoryManager.INSTANCE.getActiveRepository();
      if (activeRepository == null)
      {
        originalForeground = repositoryCombo.getForeground();
        repositoryCombo.setText("type repository url, drag and drop, or pick from list");
        repositoryCombo.setForeground(gray);
      }
      else
      {
        if (!activeRepository.equals(repositoryCombo.getText()))
        {
          repositoryCombo.setText(activeRepository);
        }
      }
    }
  }

  /**
   * @author Eike Stepper
   */
  private final class RepositoryHistoryListener extends KeyAdapter implements ISelectionChangedListener
  {
    private boolean listVisible;

    private String listRepository;

    @Override
    public void keyReleased(KeyEvent e)
    {
      boolean currentListVisible = repositoryCombo.getListVisible();
      if (currentListVisible)
      {
        String repository = getSelectedRepository();
        if (!StringUtil.isEmpty(repository))
        {
          listRepository = repository;
        }
      }

      if (currentListVisible && (e.keyCode == SWT.DEL || e.keyCode == SWT.BS))
      {
        RepositoryManager.INSTANCE.removeRepository(listRepository);
      }
      else if (e.keyCode == SWT.CR && listVisible && !currentListVisible)
      {
        selectRepository();
      }

      listVisible = currentListVisible;
    }

    public void selectionChanged(SelectionChangedEvent event)
    {
      listVisible = repositoryCombo.getListVisible();
      if (!listVisible)
      {
        selectRepository();
      }
    }

    private void selectRepository()
    {
      String newRepository = getSelectedRepository();
      activateAndLoadRepository(newRepository);
    }

    private String getSelectedRepository()
    {
      IStructuredSelection selection = (IStructuredSelection)repositoryViewer.getSelection();
      return selection.isEmpty() ? repositoryCombo.getText() : (String)selection.getFirstElement();
    }
  }

  /**
   * @author Eike Stepper
   */
  private final class RepositoryContentProvider implements IStructuredContentProvider, RepositoryManagerListener
  {
    public RepositoryContentProvider()
    {
      RepositoryManager.INSTANCE.addListener(this);
    }

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

    public void dispose()
    {
      RepositoryManager.INSTANCE.removeListener(this);
    }

    public Object[] getElements(Object element)
    {
      return RepositoryManager.INSTANCE.getRepositories();
    }

    public void repositoriesChanged(RepositoryManager repositoryManager)
    {
      UIUtil.asyncExec(new Runnable()
      {
        public void run()
        {
          if (!container.isDisposed())
          {
            repositoryViewer.refresh();

            UIUtil.asyncExec(new Runnable()
            {
              public void run()
              {
                if (!container.isDisposed())
                {
                  String activeRepository = RepositoryManager.INSTANCE.getActiveRepository();
                  if (activeRepository == null)
                  {
                    repositoryViewer.setSelection(StructuredSelection.EMPTY);
                    repositoryCombo.setText("");
                  }
                  else
                  {
                    ISelection selection = new StructuredSelection(activeRepository);
                    repositoryViewer.setSelection(selection);
                    repositoryCombo.setText(activeRepository);
                    repositoryCombo.setSelection(new Point(0, activeRepository.length()));
                  }
                }
              }
            });
          }
        }
      });
    }

    public void activeRepositoryChanged(RepositoryManager repositoryManager, String repository)
    {
      // Do nothing.
    }
  }

  /**
   * @author Eike Stepper
   */
  private final class ItemContentProvider implements ITreeContentProvider
  {
    public void inputChanged(Viewer viewer, Object oldInput, Object newInput)
    {
    }

    public void dispose()
    {
    }

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

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

    public Object[] getChildren(Object element)
    {
      Item[] children = ((Item)element).getChildren();
      if (children != null)
      {
        return children;
      }

      return NO_ELEMENTS;
    }

    public boolean hasChildren(Object element)
    {
      return ((Item)element).hasChildren();
    }
  }

  /**
  * @author Eike Stepper
  */
  private static final class ItemLabelProvider extends LabelProvider
  {
    @Override
    public Image getImage(Object element)
    {
      Item item = (Item)element;
      return item.getImage();
    }

    @Override
    public String getText(Object element)
    {
      Item item = (Item)element;
      return item.getLabel();
    }
  }

  /**
   * @author Eike Stepper
   */
  private static final class VersionProvider extends LabelProvider implements IStructuredContentProvider
  {
    private static final Image IMAGE = P2UIPlugin.INSTANCE.getSWTImage("obj16/version");

    private TableViewer versionsViewer;

    private VersionSegment versionSegment;

    public VersionProvider()
    {
      try
      {
        versionSegment = VersionSegment.get(SETTINGS.get(VERSION_SEGMENT_KEY));
      }
      catch (Exception ex)
      {
        //$FALL-THROUGH$
      }

      if (versionSegment == null)
      {
        versionSegment = VersionSegment.QUALIFIER;
      }
    }

    public VersionSegment getVersionSegment()
    {
      return versionSegment;
    }

    public void setVersionSegment(VersionSegment versionSegment)
    {
      if (this.versionSegment != versionSegment)
      {
        this.versionSegment = versionSegment;
        SETTINGS.put(VERSION_SEGMENT_KEY, versionSegment.getLiteral());

        if (versionsViewer != null)
        {
          versionsViewer.refresh();
        }
      }
    }

    public void inputChanged(Viewer viewer, Object oldInput, Object newInput)
    {
      versionsViewer = (TableViewer)viewer;
    }

    @Override
    public void dispose()
    {
    }

    public Object[] getElements(Object inputElement)
    {
      if (inputElement instanceof VersionedItem)
      {
        VersionedItem versionedItem = (VersionedItem)inputElement;
        Map<Version, IMatchExpression<IInstallableUnit>> versions = versionedItem.getVersions();
        if (versions != null)
        {
          Set<ItemVersion> itemVersions = new HashSet<ItemVersion>();
          for (Map.Entry<Version, IMatchExpression<IInstallableUnit>> entry : versions.entrySet())
          {
            ItemVersion itemVersion = getItemVersion(entry.getKey(), entry.getValue());
            itemVersions.add(itemVersion);
          }

          ItemVersion[] array = itemVersions.toArray(new ItemVersion[itemVersions.size()]);
          Arrays.sort(array);
          return array;
        }
      }

      return NO_ELEMENTS;
    }

    @Override
    public Image getImage(Object element)
    {
      return IMAGE;
    }

    private ItemVersion getItemVersion(Version version, IMatchExpression<IInstallableUnit> filter)
    {
      int segments = version.getSegmentCount();
      if (segments == 0)
      {
        return new ItemVersion(version, "0.0.0", filter);
      }

      segments = Math.min(segments, versionSegment.ordinal() + 1);
      StringBuilder builder = new StringBuilder();

      for (int i = 0; i < segments; i++)
      {
        String segment = version.getSegment(i).toString();
        if (StringUtil.isEmpty(segment))
        {
          break;
        }

        if (builder.length() != 0)
        {
          builder.append('.');
        }

        builder.append(segment);
      }

      version = Version.create(builder.toString());

      if (segments < 3)
      {
        builder.append(".x");
      }

      return new ItemVersion(version, builder.toString(), filter);
    }

    /**
     * @author Eike Stepper
     */
    public static final class ItemVersion implements Comparable<ItemVersion>
    {
      private final Version version;

      private final String label;

      private final IMatchExpression<IInstallableUnit> filter;

      public ItemVersion(Version version, String label, IMatchExpression<IInstallableUnit> filter)
      {
        this.version = version;
        this.label = label;
        this.filter = filter;
      }

      public Version getVersion()
      {
        return version;
      }

      public IMatchExpression<IInstallableUnit> getFilter()
      {
        return filter;
      }

      public int compareTo(ItemVersion o)
      {
        return version.compareTo(o.version);
      }

      @Override
      public int hashCode()
      {
        return version.hashCode();
      }

      @Override
      public boolean equals(Object obj)
      {
        return version.equals(((ItemVersion)obj).version);
      }

      @Override
      public String toString()
      {
        return label;
      }
    }
  }

  /**
   * @author Eike Stepper
   */
  private static abstract class Item implements Comparable<Item>
  {
    protected static final Integer CATEGORY_ORDER = 0;

    protected static final Integer NON_CATEGORY_ORDER = 1;

    private String label;

    public Item()
    {
    }

    public abstract Image getImage();

    public String getNamespace()
    {
      return IInstallableUnit.NAMESPACE_IU_ID;
    }

    public String getName()
    {
      return getLabel();
    }

    public String getLabel()
    {
      return label;
    }

    public void setLabel(String label)
    {
      this.label = label;
    }

    public Item[] getChildren()
    {
      return null;
    }

    public boolean hasChildren()
    {
      return false;
    }

    @Override
    public String toString()
    {
      return label;
    }

    @Override
    public final int hashCode()
    {
      return super.hashCode();
    }

    @Override
    public final boolean equals(Object obj)
    {
      return super.equals(obj);
    }

    public int compareTo(Item o)
    {
      Integer category1 = getCategoryOrder();
      Integer category2 = o.getCategoryOrder();

      int result = category1.compareTo(category2);
      if (result == 0)
      {
        String label1 = label.toLowerCase();
        String label2 = o.label.toLowerCase();
        result = label1.compareTo(label2);
      }

      return result;
    }

    protected Integer getCategoryOrder()
    {
      return NON_CATEGORY_ORDER;
    }
  }

  /**
   * @author Eike Stepper
   */
  private static final class LoadingItem extends Item
  {
    private static final Image IMAGE = P2UIPlugin.INSTANCE.getSWTImage("obj16/repository");

    private final URI location;

    public LoadingItem(URI location)
    {
      this.location = location;
    }

    @Override
    public Image getImage()
    {
      return IMAGE;
    }

    @Override
    public String getLabel()
    {
      return "Loading " + location;
    }
  }

  /**
   * @author Eike Stepper
   */
  private static final class ErrorItem extends Item
  {
    private final IStatus status;

    public ErrorItem(IStatus status)
    {
      this.status = status;
    }

    @Override
    public Image getImage()
    {
      return UIUtil.getStatusImage(status.getSeverity());
    }

    @Override
    public String getLabel()
    {
      return status.getMessage();
    }
  }

  /**
   * @author Eike Stepper
   */
  private static final class CategoryItem extends Item
  {
    private static final Image IMAGE = P2UIPlugin.INSTANCE.getSWTImage("obj16/category");

    private Item[] children;

    public CategoryItem()
    {
    }

    @Override
    public Image getImage()
    {
      return IMAGE;
    }

    @Override
    public boolean hasChildren()
    {
      return children != null && children.length != 0;
    }

    @Override
    public Item[] getChildren()
    {
      return children;
    }

    public void setChildren(Item[] children)
    {
      Arrays.sort(children);
      this.children = children;
    }

    @Override
    protected Integer getCategoryOrder()
    {
      return CATEGORY_ORDER;
    }
  }

  /**
   * @author Eike Stepper
   */
  private static abstract class VersionedItem extends Item
  {
    private Map<Version, IMatchExpression<IInstallableUnit>> versions;

    public VersionedItem()
    {
    }

    public Map<Version, IMatchExpression<IInstallableUnit>> getVersions()
    {
      return versions;
    }

    public void setVersions(Map<Version, IMatchExpression<IInstallableUnit>> map)
    {
      versions = map;
    }
  }

  /**
   * @author Eike Stepper
   */
  private static final class FeatureItem extends VersionedItem
  {
    private static final Image IMAGE = P2UIPlugin.INSTANCE.getSWTImage("obj16/artifactFeature");

    private final String id;

    public FeatureItem(String id)
    {
      this.id = id;
    }

    @Override
    public Image getImage()
    {
      return IMAGE;
    }

    @Override
    public String getName()
    {
      return id;
    }
  }

  /**
   * @author Eike Stepper
   */
  private static final class PluginItem extends VersionedItem
  {
    private static final Image IMAGE = P2UIPlugin.INSTANCE.getSWTImage("obj16/artifactPlugin");

    private final String id;

    public PluginItem(String id)
    {
      this.id = id;
    }

    @Override
    public Image getImage()
    {
      return IMAGE;
    }

    @Override
    public String getName()
    {
      return id;
    }
  }

  /**
   * @author Eike Stepper
   */
  private static final class CapabilityItem extends VersionedItem
  {
    private static final Image IMAGE = P2UIPlugin.INSTANCE.getSWTImage("obj16/capability");

    private static final Image FEATURE_IMAGE = P2UIPlugin.INSTANCE.getSWTImage("obj16/artifactFeature");

    private static final Image PLUGIN_IMAGE = P2UIPlugin.INSTANCE.getSWTImage("obj16/artifactPlugin");

    private static final Image PACKAGE_IMAGE = P2UIPlugin.INSTANCE.getSWTImage("full/obj16/Requirement_Package");

    private String namespace;

    public CapabilityItem()
    {
    }

    @Override
    public String getNamespace()
    {
      return namespace;
    }

    public void setNamespace(String namespace)
    {
      this.namespace = namespace;
    }

    public void setVersions(Set<Version> versions)
    {
      Map<Version, IMatchExpression<IInstallableUnit>> map = new HashMap<Version, IMatchExpression<IInstallableUnit>>();
      for (Version version : versions)
      {
        map.put(version, null);
      }

      setVersions(map);
    }

    @Override
    public Image getImage()
    {
      if (IInstallableUnit.NAMESPACE_IU_ID.equals(namespace))
      {
        if (getLabel().endsWith(Requirement.FEATURE_SUFFIX))
        {
          return FEATURE_IMAGE;
        }

        return PLUGIN_IMAGE;
      }

      if (RequirementItemProvider.NAMESPACE_PACKAGE_ID.equals(namespace))
      {
        return PACKAGE_IMAGE;
      }

      return IMAGE;
    }
  }
}
