/*
 * Copyright (c) 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.emf.cdo.explorer.ui.checkouts;

import org.eclipse.emf.cdo.CDOElement;
import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.revision.CDOList;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.common.revision.CDORevisionManager;
import org.eclipse.emf.cdo.eresource.CDOResourceFolder;
import org.eclipse.emf.cdo.eresource.CDOResourceNode;
import org.eclipse.emf.cdo.explorer.CDOExplorerManager;
import org.eclipse.emf.cdo.explorer.CDOExplorerManager.ElementsChangedEvent;
import org.eclipse.emf.cdo.explorer.CDOExplorerUtil;
import org.eclipse.emf.cdo.explorer.checkouts.CDOCheckout;
import org.eclipse.emf.cdo.explorer.checkouts.CDOCheckoutManager;
import org.eclipse.emf.cdo.explorer.checkouts.CDOCheckoutManager.CheckoutStateEvent;
import org.eclipse.emf.cdo.explorer.ui.ViewerUtil;
import org.eclipse.emf.cdo.explorer.ui.bundle.OM;
import org.eclipse.emf.cdo.explorer.ui.checkouts.actions.OpenWithActionProvider;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionCache;
import org.eclipse.emf.cdo.ui.CDOItemProvider;
import org.eclipse.emf.cdo.util.CDOUtil;
import org.eclipse.emf.cdo.view.CDOView;

import org.eclipse.net4j.util.container.IContainerEvent;
import org.eclipse.net4j.util.event.IEvent;
import org.eclipse.net4j.util.event.IListener;
import org.eclipse.net4j.util.lifecycle.LifecycleException;
import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
import org.eclipse.net4j.util.ui.UIUtil;
import org.eclipse.net4j.util.ui.views.ItemProvider;

import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
import org.eclipse.emf.edit.provider.ItemProviderAdapter;
import org.eclipse.emf.spi.cdo.InternalCDOObject;
import org.eclipse.emf.spi.cdo.InternalCDOView;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
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.IMenuManager;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.IOpenListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.ITreeSelection;
import org.eclipse.jface.viewers.OpenEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IViewReference;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.navigator.CommonViewer;
import org.eclipse.ui.navigator.ICommonContentExtensionSite;
import org.eclipse.ui.navigator.ICommonContentProvider;
import org.eclipse.ui.part.IPage;
import org.eclipse.ui.views.properties.IPropertySource;
import org.eclipse.ui.views.properties.IPropertySourceProvider;
import org.eclipse.ui.views.properties.PropertySheet;
import org.eclipse.ui.views.properties.PropertySheetPage;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author Eike Stepper
 */
public class CDOCheckoutContentProvider implements ICommonContentProvider, IPropertySourceProvider, IOpenListener
{
  private static final Map<String, CDOCheckoutContentProvider> INSTANCES = new HashMap<String, CDOCheckoutContentProvider>();

  private static final Set<Object> LOADING_OBJECTS = new HashSet<Object>();

  private static final Method GET_CHILDREN_FEATURES_METHOD = getMethod(ItemProviderAdapter.class, "getChildrenFeatures",
      Object.class);

  private static final Method FIND_ITEM_METHOD = getMethod(StructuredViewer.class, "findItem", Object.class);

  private static final CDOCheckoutManager CHECKOUT_MANAGER = CDOExplorerUtil.getCheckoutManager();

  private final IListener checkoutManagerListener = new IListener()
  {
    public void notifyEvent(IEvent event)
    {
      CDOCheckoutViewerRefresh viewerRefresh = stateManager.getViewerRefresh();

      if (event instanceof IContainerEvent)
      {
        viewerRefresh.addNotification(null, true, true);
      }
      else if (event instanceof CheckoutStateEvent)
      {
        CheckoutStateEvent e = (CheckoutStateEvent)event;
        CDOCheckout checkout = e.getCheckout();
        CDOCheckout.State state = e.getNewState();

        if (state == CDOCheckout.State.Opening)
        {
          // Trigger hasChildren().
          ViewerUtil.refresh(viewer, checkout);

          // Trigger getChildren().
          ViewerUtil.expand(viewer, checkout, true);
        }
        else
        {
          if (state == CDOCheckout.State.Closed)
          {
            ViewerUtil.expand(viewer, checkout, false);
          }

          viewerRefresh.addNotification(checkout, true, true);

          if (state == CDOCheckout.State.Open)
          {
            ViewerUtil.expand(viewer, checkout, true);
          }

          updatePropertySheetPage(checkout);
        }
      }
      else if (event instanceof CDOExplorerManager.ElementsChangedEvent)
      {
        CDOExplorerManager.ElementsChangedEvent e = (CDOExplorerManager.ElementsChangedEvent)event;
        ElementsChangedEvent.StructuralImpact structuralImpact = e.getStructuralImpact();
        Object[] changedElements = e.getChangedElements();

        if (structuralImpact != ElementsChangedEvent.StructuralImpact.NONE && changedElements.length == 1)
        {
          Object changedElement = changedElements[0];
          if (changedElement instanceof CDOElement)
          {
            changedElement = ((CDOElement)changedElement).getParent();
          }

          if (structuralImpact == ElementsChangedEvent.StructuralImpact.PARENT)
          {
            changedElement = CDOExplorerUtil.getParent(changedElement);
          }

          viewerRefresh.addNotification(changedElement, true, true);
        }
        else
        {
          for (Object changedElement : changedElements)
          {
            viewerRefresh.addNotification(changedElement, false, true);
          }
        }

        updatePropertySheetPage(changedElements);
      }
    }

    private void updatePropertySheetPage(final Object element)
    {
      IWorkbenchPage workbenchPage = getWorkbenchPage();

      PropertySheet propertySheet = getPropertySheet(workbenchPage);
      if (propertySheet != null)
      {
        final IPage currentPage = propertySheet.getCurrentPage();
        if (currentPage instanceof PropertySheetPage || currentPage instanceof TabbedPropertySheetPage)
        {
          final Control control = viewer.getControl();
          if (!control.isDisposed())
          {
            control.getDisplay().asyncExec(new Runnable()
            {
              public void run()
              {
                if (!control.isDisposed())
                {
                  IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
                  if (selection.size() == 1)
                  {
                    for (Object object : selection.toArray())
                    {
                      if (object == element)
                      {
                        if (currentPage instanceof PropertySheetPage)
                        {
                          ((PropertySheetPage)currentPage).refresh();
                        }
                        else if (currentPage instanceof TabbedPropertySheetPage)
                        {
                          ((TabbedPropertySheetPage)currentPage).refresh();
                        }

                        return;
                      }
                    }
                  }
                }
              }
            });
          }
        }
      }
    }

    private PropertySheet getPropertySheet(IWorkbenchPage workbenchPage)
    {
      for (IViewReference viewReference : workbenchPage.getViewReferences())
      {
        if ("org.eclipse.ui.views.PropertySheet".equals(viewReference.getId()))
        {
          IViewPart view = viewReference.getView(false);
          if (view instanceof PropertySheet)
          {
            return (PropertySheet)view;

          }
        }
      }

      return null;
    }
  };

  private final CDOCheckoutStateManager stateManager = new CDOCheckoutStateManager(this);

  private final Map<Object, Object[]> childrenCache = new ConcurrentHashMap<Object, Object[]>();

  private String viewerID;

  private TreeViewer viewer;

  private Object input;

  public static final String PROJECT_EXPLORER_ID = "org.eclipse.ui.navigator.ProjectExplorer";

  public CDOCheckoutContentProvider()
  {
  }

  public void init(ICommonContentExtensionSite config)
  {
    viewerID = config.getService().getViewerId();
    INSTANCES.put(viewerID, this);
    CHECKOUT_MANAGER.addListener(checkoutManagerListener);
  }

  public void saveState(IMemento aMemento)
  {
    // Do nothing.
  }

  public void restoreState(IMemento aMemento)
  {
    // Do nothing.
  }

  public void dispose()
  {
    CHECKOUT_MANAGER.removeListener(checkoutManagerListener);
    INSTANCES.remove(viewerID);
  }

  public void disposeWith(Control control)
  {
    control.addDisposeListener(new DisposeListener()
    {
      public void widgetDisposed(DisposeEvent e)
      {
        dispose();
      }
    });
  }

  public final CDOCheckoutStateManager getStateManager()
  {
    return stateManager;
  }

  public final TreeViewer getViewer()
  {
    return viewer;
  }

  public void inputChanged(Viewer newViewer, Object oldInput, Object newInput)
  {
    TreeViewer newTreeViewer = null;
    if (newViewer instanceof TreeViewer)
    {
      newTreeViewer = (TreeViewer)newViewer;
    }

    if (newTreeViewer != viewer)
    {
      if (viewer != null)
      {
        viewer.removeOpenListener(this);
      }

      viewer = newTreeViewer;

      if (viewer != null)
      {
        viewer.addOpenListener(this);
      }
    }

    input = newInput;
    stateManager.inputChanged(newTreeViewer, oldInput, newInput);
  }

  public Object getInput()
  {
    return input;
  }

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

  public boolean hasChildren(Object object)
  {
    try
    {
      if (object instanceof IResource)
      {
        if (object instanceof IWorkspaceRoot)
        {
          return !CHECKOUT_MANAGER.isEmpty();
        }

        return false;
      }

      if (object instanceof ViewerUtil.Pending)
      {
        return false;
      }

      if (object instanceof CDOCheckout)
      {
        CDOCheckout checkout = (CDOCheckout)object;
        switch (checkout.getState())
        {
        case Closing:
        case Closed:
          return false;

        case Opening:
          // This must be the ViewerUtil.Pending element.
          return true;

        case Open:
          object = checkout.getRootObject();
          break;
        }
      }

      if (object instanceof CDOElement)
      {
        CDOElement checkoutElement = (CDOElement)object;
        return checkoutElement.hasChildren();
      }

      if (GET_CHILDREN_FEATURES_METHOD != null && object instanceof EObject)
      {
        EObject eObject = (EObject)object;

        InternalCDOObject cdoObject = getCDOObject(eObject);
        if (cdoObject != null)
        {
          InternalCDORevision revision = cdoObject.cdoRevision(false);
          if (revision != null)
          {
            ITreeItemContentProvider provider = (ITreeItemContentProvider)stateManager.adapt(object,
                ITreeItemContentProvider.class);
            if (provider instanceof ItemProviderAdapter)
            {
              try
              {
                return hasChildren(cdoObject, revision, (ItemProviderAdapter)provider);
              }
              catch (Exception ex)
              {
                //$FALL-THROUGH$
              }
            }
          }
        }
      }

      ITreeContentProvider contentProvider = stateManager.getContentProvider(object);
      if (contentProvider != null)
      {
        return contentProvider.hasChildren(object);
      }
    }
    catch (LifecycleException ex)
    {
      //$FALL-THROUGH$
    }
    catch (RuntimeException ex)
    {
      if (LifecycleUtil.isActive(object))
      {
        throw ex;
      }

      //$FALL-THROUGH$
    }

    return false;
  }

  public Object[] getChildren(Object object)
  {
    try
    {
      if (object instanceof IResource)
      {
        if (object instanceof IWorkspaceRoot)
        {
          return CHECKOUT_MANAGER.getCheckouts();
        }

        return ViewerUtil.NO_CHILDREN;
      }

      if (object instanceof ViewerUtil.Pending)
      {
        return ViewerUtil.NO_CHILDREN;
      }

      if (object instanceof CDOElement)
      {
        CDOElement checkoutElement = (CDOElement)object;
        return checkoutElement.getChildren();
      }

      final Object originalObject = object;
      Object[] children = childrenCache.remove(originalObject);
      if (children != null)
      {
        return children;
      }

      CDOCheckout openingCheckout = null;
      CDOCheckout checkout = null;

      if (object instanceof CDOCheckout)
      {
        checkout = (CDOCheckout)object;

        switch (checkout.getState())
        {
        case Closing:
        case Closed:
          return ViewerUtil.NO_CHILDREN;

        case Opening:
          openingCheckout = checkout;
          break;

        case Open:
          object = checkout.getRootObject();
          break;
        }
      }

      final Object finalObject = object;
      final CDOCheckout finalOpeningCheckout = openingCheckout;
      final CDOCheckout finalCheckout = checkout;
      final ITreeContentProvider contentProvider = stateManager.getContentProvider(finalObject);
      if (contentProvider == null)
      {
        return ItemProvider.NO_ELEMENTS;
      }

      final List<CDORevision> loadedRevisions = new ArrayList<CDORevision>();
      final List<CDOID> missingIDs = new ArrayList<CDOID>();

      if (openingCheckout == null)
      {
        children = determineChildRevisions(object, loadedRevisions, missingIDs);
        if (children != null)
        {
          return CDOCheckoutContentModifier.Registry.INSTANCE.modifyChildren(object, children);
        }
      }

      synchronized (LOADING_OBJECTS)
      {
        LOADING_OBJECTS.add(originalObject);
      }

      new Job("Load " + finalObject)
      {
        @Override
        protected IStatus run(IProgressMonitor monitor)
        {
          try
          {
            if (finalOpeningCheckout != null)
            {
              finalOpeningCheckout.open();
              determineChildRevisions(finalObject, loadedRevisions, missingIDs);
            }

            if (!missingIDs.isEmpty())
            {
              CDOObject cdoObject = getCDOObject((EObject)finalObject);
              CDOView view = cdoObject.cdoView();
              CDORevisionManager revisionManager = view.getSession().getRevisionManager();

              List<CDORevision> revisions = revisionManager.getRevisions(missingIDs, view, CDORevision.UNCHUNKED,
                  CDORevision.DEPTH_NONE, true);
              loadedRevisions.addAll(revisions);
            }

            Object[] children;
            CDOCheckout checkout = finalCheckout != null ? finalCheckout : CDOExplorerUtil.getCheckout(finalObject);
            synchronized (checkout.getView())
            {
              children = contentProvider.getChildren(finalObject);
            }

            // Adjust possible legacy adapters.
            for (int i = 0; i < children.length; i++)
            {
              Object child = children[i];
              if (child instanceof InternalCDOObject)
              {
                InternalCDOObject cdoObject = (InternalCDOObject)child;
                InternalEObject instance = cdoObject.cdoInternalInstance();
                if (instance != cdoObject)
                {
                  children[i] = instance;
                }
              }
            }

            children = CDOCheckoutContentModifier.Registry.INSTANCE.modifyChildren(finalObject, children);
            childrenCache.put(originalObject, children);
          }
          catch (final Exception ex)
          {
            childrenCache.remove(originalObject);

            if (finalOpeningCheckout != null)
            {
              finalOpeningCheckout.close();
            }

            OM.LOG.error(ex);

            final Control control = viewer.getControl();
            if (!control.isDisposed())
            {
              UIUtil.getDisplay().asyncExec(new Runnable()
              {
                public void run()
                {
                  try
                  {
                    if (!control.isDisposed())
                    {
                      Shell shell = control.getShell();
                      String title = (finalOpeningCheckout != null ? "Open" : "Load") + " Error";
                      MessageDialog.openError(shell, title, ex.getMessage());
                    }
                  }
                  catch (Exception ex)
                  {
                    OM.LOG.error(ex);
                  }
                }
              });
            }
          }

          CDOCheckoutViewerRefresh viewerRefresh = stateManager.getViewerRefresh();
          viewerRefresh.addNotification(originalObject, true, true, new Runnable()
          {
            public void run()
            {
              synchronized (LOADING_OBJECTS)
              {
                LOADING_OBJECTS.remove(originalObject);
              }
            }
          });

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

      if (FIND_ITEM_METHOD != null)
      {
        try
        {
          Object widget = FIND_ITEM_METHOD.invoke(viewer, originalObject);
          if (widget instanceof TreeItem)
          {
            TreeItem item = (TreeItem)widget;
            TreeItem[] childItems = item.getItems();

            int childCount = childItems.length;
            if (childCount != 0)
            {
              List<Object> result = new ArrayList<Object>();
              for (int i = 0; i < childCount; i++)
              {
                TreeItem childItem = childItems[i];
                Object child = childItem.getData();
                if (child != null)
                {
                  result.add(child);
                }
              }

              int size = result.size();
              if (size != 0)
              {
                return result.toArray(new Object[size]);
              }
            }
          }
        }
        catch (Exception ex)
        {
          //$FALL-THROUGH$
        }
      }

      String text = "Loading...";
      if (finalOpeningCheckout != null)
      {
        text = "Opening...";
      }

      return new Object[] { new ViewerUtil.Pending(originalObject, text) };
    }
    catch (LifecycleException ex)
    {
      //$FALL-THROUGH$
    }
    catch (RuntimeException ex)
    {
      if (LifecycleUtil.isActive(object))
      {
        throw ex;
      }

      //$FALL-THROUGH$
    }

    return ItemProvider.NO_ELEMENTS;
  }

  private Object[] determineChildRevisions(Object object, List<CDORevision> loadedRevisions, List<CDOID> missingIDs)
  {
    if (GET_CHILDREN_FEATURES_METHOD != null && object instanceof EObject)
    {
      EObject eObject = (EObject)object;

      InternalCDOObject cdoObject = getCDOObject(eObject);
      if (cdoObject != null)
      {
        InternalCDORevision revision = cdoObject.cdoRevision(false);
        if (revision != null)
        {
          ITreeItemContentProvider provider = (ITreeItemContentProvider)stateManager.adapt(object,
              ITreeItemContentProvider.class);
          if (provider instanceof ItemProviderAdapter)
          {
            try
            {
              determineChildRevisions(cdoObject, revision, (ItemProviderAdapter)provider, loadedRevisions, missingIDs);
            }
            catch (Exception ex)
            {
              //$FALL-THROUGH$
            }

            if (missingIDs.isEmpty())
            {
              // All revisions are cached. Just return the objects without server round-trips.
              ITreeContentProvider contentProvider = stateManager.getContentProvider(object);
              if (contentProvider != null)
              {
                return contentProvider.getChildren(object);
              }
            }
          }
        }
      }
    }

    return null;
  }

  public Object getParent(Object object)
  {
    try
    {
      if (object instanceof CDOCheckout)
      {
        return ResourcesPlugin.getWorkspace().getRoot();
      }

      if (object instanceof ViewerUtil.Pending)
      {
        return ((ViewerUtil.Pending)object).getParent();
      }

      if (object instanceof CDOElement)
      {
        CDOElement checkoutElement = (CDOElement)object;
        return checkoutElement.getParent();
      }

      if (object instanceof EObject)
      {
        EObject eObject = CDOUtil.getEObject((EObject)object);

        CDOElement element = CDOElement.getFor(eObject);
        if (element != null)
        {
          return element;
        }

        ITreeContentProvider contentProvider = stateManager.getContentProvider(object);
        if (contentProvider != null)
        {
          Object parent = contentProvider.getParent(object);
          if (parent instanceof EObject)
          {
            EObject eParent = (EObject)parent;
            Adapter adapter = EcoreUtil.getAdapter(eParent.eAdapters(), CDOCheckout.class);
            if (adapter != null)
            {
              return adapter;
            }
          }

          return parent;
        }
      }
    }
    catch (LifecycleException ex)
    {
      //$FALL-THROUGH$
    }
    catch (RuntimeException ex)
    {
      if (LifecycleUtil.isActive(object))
      {
        throw ex;
      }

      //$FALL-THROUGH$
    }

    return null;
  }

  public IPropertySource getPropertySource(Object object)
  {
    IPropertySourceProvider contentProvider = stateManager.getContentProvider(object);
    if (contentProvider != null)
    {
      return contentProvider.getPropertySource(object);
    }

    return null;
  }

  public void selectObjects(final Object... objects)
  {
    final Control control = viewer.getControl();
    if (!control.isDisposed())
    {
      final long end = System.currentTimeMillis() + 5000L;
      final Display display = control.getDisplay();
      display.asyncExec(new Runnable()
      {
        public void run()
        {
          if (control.isDisposed())
          {
            return;
          }

          for (Object object : objects)
          {
            LinkedList<Object> path = new LinkedList<Object>();
            CDOCheckout checkout = CDOExplorerUtil.walkUp(object, path);
            if (checkout != null)
            {
              viewer.setExpandedState(checkout, true);

              if (!path.isEmpty())
              {
                path.removeFirst();
              }

              if (!path.isEmpty())
              {
                path.removeLast();
              }

              for (Object parent : path)
              {
                viewer.setExpandedState(parent, true);
              }
            }
          }

          viewer.setSelection(new StructuredSelection(objects), true);
          IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();

          Set<Object> actual = new HashSet<Object>(Arrays.asList(selection.toArray()));
          Set<Object> expected = new HashSet<Object>(Arrays.asList(objects));

          if (!actual.equals(expected))
          {
            if (isObjectLoading(objects) || System.currentTimeMillis() < end)
            {
              display.timerExec(50, this);
            }
          }
        }
      });
    }
  }

  public void open(OpenEvent event)
  {
    ISelection selection = event.getSelection();
    if (selection instanceof IStructuredSelection)
    {
      IStructuredSelection ssel = (IStructuredSelection)selection;
      if (ssel.size() == 1)
      {
        Object element = ssel.getFirstElement();
        if (element instanceof CDOCheckout)
        {
          final CDOCheckout checkout = (CDOCheckout)element;
          if (checkout.getState() == CDOCheckout.State.Closed)
          {
            // Simulate CheckoutOpenHandler.
            new Job("Open " + checkout.getLabel())
            {
              @Override
              protected IStatus run(IProgressMonitor monitor)
              {
                try
                {
                  checkout.open();
                }
                catch (Exception ex)
                {
                  OM.LOG.error(ex);
                }

                return Status.OK_STATUS;
              }
            }.schedule();
          }
        }
        else if (element instanceof CDOResourceNode)
        {
          // Do nothing special.
        }
        else if (element instanceof EObject)
        {
          EObject eObject = (EObject)element;

          Shell shell = getWorkbenchPage().getWorkbenchWindow().getShell();
          ComposedAdapterFactory adapterFactory = stateManager.getAdapterFactory(eObject);
          OpenWithActionProvider.editObject(shell, adapterFactory, eObject);
        }
      }
    }
  }

  private IWorkbenchPage getWorkbenchPage()
  {
    if (viewer instanceof CommonViewer)
    {
      CommonViewer commonViewer = (CommonViewer)viewer;
      return commonViewer.getCommonNavigator().getSite().getPage();
    }

    return PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
  }

  private static InternalCDOObject getCDOObject(EObject eObject)
  {
    return (InternalCDOObject)CDOUtil.getCDOObject(eObject, false);
  }

  private static boolean hasChildren(InternalCDOObject cdoObject, InternalCDORevision revision,
      ItemProviderAdapter provider) throws Exception
  {
    for (EStructuralFeature feature : getChildrenFeatures(cdoObject, provider))
    {
      if (feature.isMany())
      {
        if (!revision.isEmpty(feature))
        {
          return true;
        }
      }
      else if (revision.getValue(feature) != null)
      {
        return true;
      }
    }

    return false;
  }

  private static void determineChildRevisions(InternalCDOObject cdoObject, InternalCDORevision revision,
      ItemProviderAdapter provider, List<CDORevision> loadedRevisions, List<CDOID> missingIDs) throws Exception
  {
    InternalCDOView view = cdoObject.cdoView();
    InternalCDORevisionCache revisionCache = view.getSession().getRevisionManager().getCache();

    for (EStructuralFeature feature : getChildrenFeatures(cdoObject, provider))
    {
      if (feature.isMany())
      {
        CDOList list = revision.getList(feature);
        for (Object object : list)
        {
          determineChildRevision(loadedRevisions, missingIDs, view, revisionCache, object);
        }
      }
      else
      {
        Object value = revision.getValue(feature);
        determineChildRevision(loadedRevisions, missingIDs, view, revisionCache, value);
      }
    }
  }

  private static void determineChildRevision(List<CDORevision> loadedRevisions, List<CDOID> missingIDs,
      InternalCDOView view, InternalCDORevisionCache cache, Object object)
  {
    if (object instanceof CDOID)
    {
      CDOID id = (CDOID)object;
      CDORevision childRevision = cache.getRevision(id, view);
      if (childRevision != null)
      {
        loadedRevisions.add(childRevision);
      }
      else
      {
        missingIDs.add(id);
      }
    }
  }

  @SuppressWarnings("unchecked")
  private static Collection<? extends EStructuralFeature> getChildrenFeatures(InternalCDOObject cdoObject,
      ItemProviderAdapter provider) throws Exception
  {
    return (Collection<? extends EStructuralFeature>)GET_CHILDREN_FEATURES_METHOD.invoke(provider, cdoObject);
  }

  private static Method getMethod(Class<?> c, String methodName, Class<?>... parameterTypes)
  {
    try
    {
      Method method = c.getDeclaredMethod(methodName, parameterTypes);
      method.setAccessible(true);
      return method;
    }
    catch (Throwable ex)
    {
      return null;
    }
  }

  private static boolean isObjectLoading(Object... objects)
  {
    synchronized (LOADING_OBJECTS)
    {
      for (Object object : objects)
      {
        if (LOADING_OBJECTS.contains(object))
        {
          return true;
        }
      }

      return false;
    }
  }

  public static TreeViewer createTreeViewer(Composite container)
  {
    // TODO This is not lazy, async:
    CDOItemProvider parentItemProvider = new CDOItemProvider(null)
    {
      @Override
      public boolean hasChildren(Object element)
      {
        return getChildren(element).length != 0;
      }

      @Override
      public Object[] getChildren(Object element)
      {
        List<Object> children = new ArrayList<Object>();
        for (Object child : doGetChildren(element))
        {
          if (child instanceof CDOCheckout || child instanceof CDOResourceFolder)
          {
            children.add(child);
          }
        }

        return children.toArray();
      }

      private Object[] doGetChildren(Object element)
      {
        if (element instanceof CDOCheckout)
        {
          CDOCheckout checkout = (CDOCheckout)element;
          if (checkout.isOpen())
          {
            return checkout.getRootObject().eContents().toArray();
          }
        }

        return super.getChildren(element);
      }

      @Override
      public void fillContextMenu(IMenuManager manager, ITreeSelection selection)
      {
        // Do nothing.
      }
    };

    CDOCheckoutContentProvider contentProvider = new CDOCheckoutContentProvider();
    contentProvider.disposeWith(container);

    CDOCheckoutLabelProvider labelProvider = new CDOCheckoutLabelProvider(contentProvider);

    TreeViewer parentViewer = new TreeViewer(container, SWT.BORDER);
    parentViewer.setContentProvider(parentItemProvider);
    parentViewer.setLabelProvider(labelProvider);
    parentViewer.setInput(CDOExplorerUtil.getCheckoutManager());
    return parentViewer;
  }

  public static final CDOCheckoutContentProvider getInstance(String viewerID)
  {
    return INSTANCES.get(viewerID);
  }
}
