/**
 * Copyright (c) 2002-2007 IBM Corporation and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 *
 * Contributors:
 *   IBM - Initial API and implementation
 */
package org.eclipse.xsd.presentation;


import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.EventObject;
import java.util.LinkedList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.helpers.DefaultHandler;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.action.IContributionManager;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.action.SubContributionItem;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentListener;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.IVerticalRuler;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
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.dnd.DND;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.actions.WorkspaceModifyOperation;
import org.eclipse.ui.dialogs.SaveAsDialog;
import org.eclipse.ui.editors.text.TextEditor;
import org.eclipse.ui.ide.IGotoMarker;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.part.MultiPageEditorPart;
import org.eclipse.ui.part.MultiPageSelectionProvider;
import org.eclipse.ui.views.contentoutline.ContentOutline;
import org.eclipse.ui.views.contentoutline.ContentOutlinePage;
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
import org.eclipse.ui.views.properties.IPropertyDescriptor;
import org.eclipse.ui.views.properties.IPropertySheetPage;
import org.eclipse.ui.views.properties.IPropertySource;
import org.eclipse.ui.views.properties.PropertySheet;
import org.eclipse.ui.views.properties.PropertySheetPage;
import org.eclipse.emf.common.command.AbstractCommand;
import org.eclipse.emf.common.command.BasicCommandStack;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.command.CommandStack;
import org.eclipse.emf.common.command.CommandStackListener;
import org.eclipse.emf.common.ui.ViewerPane;
import org.eclipse.emf.common.ui.celleditor.ExtendedComboBoxCellEditor;
import org.eclipse.emf.common.ui.viewer.IViewerProvider;
import org.eclipse.emf.common.util.BasicMonitor;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.xmi.XMLLoad;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.eclipse.emf.ecore.xmi.impl.SAXXMLHandler;
import org.eclipse.emf.ecore.xmi.impl.XMLLoadImpl;
import org.eclipse.emf.ecore.xmi.impl.XMLResourceFactoryImpl;
import org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl;
import org.eclipse.emf.ecore.xml.type.internal.DataValue.EncodingMap;
import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.domain.IEditingDomainProvider;
import org.eclipse.emf.edit.provider.AdapterFactoryItemDelegator;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.provider.IDisposable;
import org.eclipse.emf.edit.provider.IItemPropertyDescriptor;
import org.eclipse.emf.edit.provider.IItemPropertySource;
import org.eclipse.emf.edit.provider.ItemProvider;
import org.eclipse.emf.edit.ui.action.CreateChildAction;
import org.eclipse.emf.edit.ui.action.CreateSiblingAction;
import org.eclipse.emf.edit.ui.action.EditingDomainActionBarContributor;
import org.eclipse.emf.edit.ui.celleditor.AdapterFactoryTreeEditor;
import org.eclipse.emf.edit.ui.dnd.EditingDomainViewerDropAdapter;
import org.eclipse.emf.edit.ui.dnd.LocalTransfer;
import org.eclipse.emf.edit.ui.dnd.ViewerDragAdapter;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
import org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry;
import org.eclipse.emf.edit.ui.provider.PropertyDescriptor;
import org.eclipse.emf.edit.ui.provider.PropertySource;
import org.eclipse.emf.edit.ui.util.EditUIUtil;
import org.eclipse.emf.edit.ui.view.ExtendedPropertySheetPage;
import org.eclipse.xsd.XSDAttributeDeclaration;
import org.eclipse.xsd.XSDAttributeGroupDefinition;
import org.eclipse.xsd.XSDAttributeUse;
import org.eclipse.xsd.XSDComplexTypeDefinition;
import org.eclipse.xsd.XSDConcreteComponent;
import org.eclipse.xsd.XSDDiagnostic;
import org.eclipse.xsd.XSDDiagnosticSeverity;
import org.eclipse.xsd.XSDElementDeclaration;
import org.eclipse.xsd.XSDModelGroup;
import org.eclipse.xsd.XSDModelGroupDefinition;
import org.eclipse.xsd.XSDPackage;
import org.eclipse.xsd.XSDParticle;
import org.eclipse.xsd.XSDSchema;
import org.eclipse.xsd.XSDSimpleTypeDefinition;
import org.eclipse.xsd.XSDTypeDefinition;
import org.eclipse.xsd.ecore.XSDEcoreBuilder;
import org.eclipse.xsd.provider.XSDItemProviderAdapterFactory;
import org.eclipse.xsd.provider.XSDSemanticItemProviderAdapterFactory;
import org.eclipse.xsd.util.XSDParser;
import org.eclipse.xsd.util.XSDResourceFactoryImpl;
import org.eclipse.xsd.util.XSDResourceImpl;
import org.eclipse.xsd.util.XSDSwitch;



/**
 * This is a an example of a xsd model editor.
 */
public class XSDEditor
  extends MultiPageEditorPart
  implements IEditingDomainProvider, ISelectionProvider, IMenuListener, IViewerProvider
{
  /**
   * This keeps track of the root object of the model.
   */
  protected XSDSchema xsdSchema;

  /**
   * This keeps track of the editing domain that is used to track all changes to the model.
   */
  protected AdapterFactoryEditingDomain editingDomain;

  /**
   * This is the adapter factory used for providing the syntactic views of the model.
   */
  protected ComposedAdapterFactory syntacticAdapterFactory;

  /**
   * This is the adapter factory used for providing the semantic views of the model.
   */
  protected ComposedAdapterFactory semanticAdapterFactory;

  /**
   * This is the content outline page.
   */
  protected IContentOutlinePage contentOutlinePage;

  /**
   * This is a kludge...
   */
  protected IStatusLineManager contentOutlineStatusLineManager;

  /**
   * This is the content outline page's viewer.
   */
  protected TreeViewer contentOutlineViewer;

  /**
   * This is the property sheet page.
   */
  protected PropertySheetPage propertySheetPage;

  /**
   * This source part of the editor.
   */
  protected TextEditor textEditor;
  protected ISourceViewer sourceViewer;

  /**
   * This is the syntactic viewer that shadows the selection in the content outline.
   * The parent relation must be correctly defined for this to work.
   */
  protected TreeViewer syntacticSelectionViewer;

  /**
   * This is the semantic viewer that shadows the selection in the content outline.
   */
  protected TreeViewer semanticSelectionViewer;

  /**
   * This keeps track of the active viewer pane, in the book.
   */
  protected ViewerPane currentViewerPane;

  /**
   * This keeps track of the active content viewer, which may be either one of the viewers in the pages or the content outline viewer.
   */
  protected Viewer currentViewer;

  /**
   * This listens to which ever viewer is active.
   */
  protected ISelectionChangedListener selectionChangedListener;

  /**
   * This keeps track of all the {@link org.eclipse.jface.viewers.ISelectionChangedListener}s that are listening to this editor.
   */
  protected Collection<ISelectionChangedListener> selectionChangedListeners = new ArrayList<ISelectionChangedListener>();

  /**
   * This keeps track of the selection of the editor as a whole.
   */
  protected ISelection editorSelection = StructuredSelection.EMPTY;

  /**
   * This is the outline action to select the next unresolved component.
   */
  protected SelectDiagnosticAction selectNextDiagnosticsAction;

  /**
   * This is the outline action to select the previous unresolved component.
   */
  protected SelectDiagnosticAction selectPreviousDiagnosticsAction;

  /**
   * This is the outline action to select the next use of a component.
   */
  protected SelectUseAction selectNextUseAction;

  /**
   * This is the outline action to select the previous use of a component.
   */
  protected SelectUseAction selectPreviousUseAction;

  /**
   * This listens for when things becomes active.
   */
  protected IPartListener partListener =
    new IPartListener()
    {
      public void partActivated(IWorkbenchPart p)
      {
        handlePartActivated(p);
      }
      public void partBroughtToTop(IWorkbenchPart p)
      {
        // Ignore
      }
      public void partClosed(IWorkbenchPart p)
      {
        // Ignore
      }
      public void partDeactivated(IWorkbenchPart p)
      {
        // Ignore
      }
      public void partOpened(IWorkbenchPart p)
      {
        // Ignore
      }
    };

  /**
   * This creates a model editor.
   */
  public XSDEditor()
  {
    super();

    // Create an adapter factory that yields item providers.
    //
    syntacticAdapterFactory = new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE);
    syntacticAdapterFactory.addAdapterFactory(new XSDItemProviderAdapterFactory());
    semanticAdapterFactory = new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE);
    semanticAdapterFactory.addAdapterFactory(new XSDSemanticItemProviderAdapterFactory());

    // Create the command stack that will notify this editor as commands are executed.
    //
    BasicCommandStack commandStack = new BasicCommandStack();

    // Add a listener to set the most recent command's affected objects to be the selection of the viewer with focus.
    //
    commandStack.addCommandStackListener
      (new CommandStackListener()
       {
         public void commandStackChanged(final EventObject event)
         {
           getContainer().getDisplay().asyncExec
             (new Runnable()
              {
                public void run()
                {
                  firePropertyChange(IEditorPart.PROP_DIRTY);

                  // Try to select the affected objects.
                  //
                  Command mostRecentCommand = ((CommandStack)event.getSource()).getMostRecentCommand();
                  if (mostRecentCommand != null)
                  {
                    setSelectionToViewer(mostRecentCommand.getAffectedObjects());
                  }

                  if (!(mostRecentCommand instanceof AbstractCommand.NonDirtying))
                  {
                    handleStructuredModelChange();
                  }

                  updateActions();

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

         }
       });

    // Create the editing domain with a special command stack.
    //
    editingDomain = new AdapterFactoryEditingDomain(syntacticAdapterFactory, commandStack);

    // Register our xsd resource factory for this context.
    //
    editingDomain.getResourceSet().getResourceFactoryRegistry().getExtensionToFactoryMap().put("xsd", new XSDResourceFactoryImpl());
  }

  protected void updateActions()
  {
    if (selectNextDiagnosticsAction != null)
    {
      selectNextDiagnosticsAction.updateAction();
      selectPreviousDiagnosticsAction.updateAction();

      selectNextUseAction.updateAction();
      selectPreviousUseAction.updateAction();
    }
  }

  protected String determineEncoding()
  {
    String encoding = (String)((XSDResourceImpl)xsdSchema.eResource()).getDefaultSaveOptions().get(XSDResourceImpl.XSD_ENCODING);
    if (encoding != null && EncodingMap.getIANA2JavaMapping(encoding) != null)
    {
      encoding = EncodingMap.getIANA2JavaMapping(encoding);
    }
    return encoding;
  }

  protected boolean handledStructuredModelChange = false;
  protected void handleStructuredModelChange()
  {
    IDocument document = textEditor.getDocumentProvider().getDocument(textEditor.getEditorInput());
    if (xsdSchema.getElement() == null)
    {
      xsdSchema.updateElement();
    }

    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try
    {
      xsdSchema.eResource().save(out, null);

      String encoding = determineEncoding();
      String newContent = encoding == null ? out.toString() : out.toString(encoding);
      String oldContent = document.get();

      int startIndex = 0;
      while (startIndex < newContent.length() &&
               startIndex < oldContent.length() &&
               newContent.charAt(startIndex) == oldContent.charAt(startIndex))
      {
        ++startIndex;
      }
      int newEndIndex = newContent.length() - 1;
      int oldEndIndex = oldContent.length() - 1;
      while (newEndIndex >= startIndex &&
               oldEndIndex >= startIndex &&
               newContent.charAt(newEndIndex) == oldContent.charAt(oldEndIndex))
      {
        --newEndIndex;
        --oldEndIndex;
      }

      String replacement = newContent.substring(startIndex, newEndIndex + 1);
      int length = oldEndIndex - startIndex + 1;
      handledStructuredModelChange = true;
      document.replace(startIndex, length, replacement);
    }
    catch (Exception exception)
    {
      XSDEditorPlugin.INSTANCE.log(exception);
    }
  }

  /**
   * This handles part activation.
   */
  protected void handlePartActivated(IWorkbenchPart workbenchPart)
  {
    if (workbenchPart == this)
    {
      if (getActivePage() == 0)
      {
        setCurrentViewer((Viewer)sourceViewer);
      }
    }
    else if (workbenchPart instanceof ContentOutline)
    {
      if (((ContentOutline)workbenchPart).getCurrentPage() == contentOutlinePage)
      {
        getEditorSite().getActionBarContributor().setActiveEditor(XSDEditor.this);

        setCurrentViewer(contentOutlineViewer);
      }
    }
    else if (workbenchPart instanceof PropertySheet)
    {
      if (((PropertySheet)workbenchPart).getCurrentPage() == propertySheetPage)
      {
        getActionBarContributor().setActiveEditor(XSDEditor.this);
      }
    }
  }

  /**
   * This is here for the listener to be able to call it.
   */
  @Override
  protected void firePropertyChange(int action)
  {
    super.firePropertyChange(action);
  }

  /**
   * This sets the selection into whichever viewer is active.
   */
  public void setSelectionToViewer(final Collection<?> collection)
  {
    // Make sure it's okay.
    //
    if (collection != null && !collection.isEmpty())
    {
      Runnable runnable =
       new Runnable()
        {
          public void run()
          {
            Viewer viewer = currentViewer;
            if (viewer == sourceViewer)
            {
              if (contentOutlineViewer != null && !contentOutlineViewer.getControl().isDisposed())
              {
                viewer = contentOutlineViewer;
              }
            }

            // Try to select the items in the current content viewer of the editor.
            //
            if (viewer != null)
            {
              StructuredSelection selection = new StructuredSelection(collection.toArray());
              viewer.setSelection(selection, true);
              if (currentViewer == sourceViewer)
              {
                handleContentOutlineSelectionForTextEditor(selection, true);
              }
            }
          }
        };
      getSite().getShell().getDisplay().asyncExec(runnable);
    }
  }

  /**
   * This returns the editing domain as required by the {@link IEditingDomainProvider} interface.
   * This is important for implementing the static methods of {@link AdapterFactoryEditingDomain}
   * and for supporting {@link org.eclipse.emf.edit.ui.action.CommandAction}.
   */
  public EditingDomain getEditingDomain()
  {
    return editingDomain;
  }

  public void setCurrentViewerPane(ViewerPane viewerPane)
  {
    if (currentViewerPane != viewerPane)
    {
      if (currentViewerPane != null)
      {
        currentViewerPane.showFocus(false);
      }
      currentViewerPane = viewerPane;
    }

    if (currentViewerPane != null)
    {
      setCurrentViewer(currentViewerPane.getViewer());
    }
  }

  /**
   * This makes sure that one content viewer, either for the current page or the outline view, if it has focus,
   * is the current one.
   */
  public void setCurrentViewer(Viewer viewer)
  {
    // If it is changing...
    //
    if (currentViewer != viewer)
    {
      if (selectionChangedListener == null)
      {
        // Create the listener on demand.
        //
        selectionChangedListener =
          new ISelectionChangedListener()
          {
            // This just notifies those things that are affected by the section.
            //
            public void selectionChanged(SelectionChangedEvent selectionChangedEvent)
            {
              setSelection(selectionChangedEvent.getSelection());
            }
          };
      }

      // Stop listening to the old one.
      //
      if (currentViewer != null)
      {
        currentViewer.removeSelectionChangedListener(selectionChangedListener);
      }

      // Start listening to the new one.
      //
      if (viewer != null)
      {
        viewer.addSelectionChangedListener(selectionChangedListener);
      }

      // Remember it.
      //
      currentViewer = viewer;

      // Set the editors selection based on the current viewer's selection.
      //
      setSelection(currentViewer == null ? StructuredSelection.EMPTY : currentViewer.getSelection());
    }
  }

  /**
   * This is the contributor for the XSD model editor.
   */
  static public class ActionBarContributor
    extends EditingDomainActionBarContributor
    implements ISelectionChangedListener
  {
    protected IEditorPart activeEditorPart;
    protected ISelectionProvider selectionProvider;

    /**
     * This action refreshes the viewer of the current editor if the editor
     * implements {@link org.eclipse.emf.common.ui.viewer.IViewerProvider}.
     */
    protected IAction refreshViewerAction =
      new Action(XSDEditorPlugin.INSTANCE.getString("_UI_RefreshViewer_menu_item"))
      {
        @Override
        public boolean isEnabled()
        {
          return activeEditorPart instanceof IViewerProvider;
        }

        @Override
        public void run()
        {
          if (activeEditorPart instanceof IViewerProvider)
          {
            Viewer viewer = ((IViewerProvider)activeEditorPart).getViewer();
            if (viewer != null)
            {
              viewer.refresh();
            }
          }
        }
      };

    /**
     * This action opens the Properties view.
     */
    protected IAction showPropertiesViewAction =
      new Action(XSDEditorPlugin.INSTANCE.getString("_UI_ShowPropertiesView_menu_item"))
      {
        @Override
        public void run()
        {
          try
          {
            getPage().showView("org.eclipse.ui.views.PropertySheet");
          }
          catch (PartInitException exception)
          {
            XSDEditorPlugin.INSTANCE.log(exception);
          }
        }
      };

    /**
     * This action enable or disable automatic validation.
     */
    protected IAction validateAutomaticallyAction =
      new Action(XSDEditorPlugin.INSTANCE.getString("_UI_ValidateAutomatically_menu_item"))
      {
        @Override
        public void run()
        {
          ((XSDEditor)activeEditorPart).setValidateAutomatically(isChecked());
        }
      };

    /**
     * This will contain one CreateChildAction corresponding to each
     * descriptor generated for the current selection.
     */
    protected Collection<IAction> createChildActions = Collections.emptyList();

    /**
     * This is the menu manager into which menu contribution items should be
     * added for the child creation actions.
     */
    protected IMenuManager createChildMenuManager;

    /**
     * This will contain one CreateSiblingAction corresponding to each
     * descriptor generated for the current selection's parent.
     */
    protected Collection<IAction> createSiblingActions = Collections.emptyList();

    /**
     * This is the menu manager into which menu contribution items should be
     * added for sibling creation actions.
     */
    protected IMenuManager createSiblingMenuManager;

    /**
     * This creates an instance of the contributor.
     */
    public ActionBarContributor()
    {
      super(ADDITIONS_LAST_STYLE);
    }

    /**
     * This adds to the menu bar a menu for editor actions, duplicating
     * the menu contribution made in the plugin.xml, so that the new menu is
     * accessible for modification in code.  Also, sub-menus are created for
     * the addition and removal of child and sibling creation items.
     */
    @Override
    public void contributeToMenu(IMenuManager menuManager)
    {
      super.contributeToMenu(menuManager);

      // duplicate the menu contribution in the plugin.xml
      IMenuManager submenuManager = new MenuManager(XSDEditorPlugin.INSTANCE.getString("_UI_XSDEditor_menu"), "org.eclipse.xsdMenuID");
      menuManager.insertAfter("additions", submenuManager);
      submenuManager.add(new Separator("settings"));
      submenuManager.add(new Separator("actions"));
      submenuManager.add(new Separator("additions"));
      submenuManager.add(new Separator("additions-end"));

      // prepare for child and sibling creation item addition/removal
      createChildMenuManager = new MenuManager(XSDEditorPlugin.INSTANCE.getString("_UI_CreateChild_menu_item"));
      createSiblingMenuManager = new MenuManager(XSDEditorPlugin.INSTANCE.getString("_UI_CreateSibling_menu_item"));
      submenuManager.insertBefore("additions", new Separator("actions"));
      submenuManager.insertBefore("additions", createChildMenuManager);
      submenuManager.insertBefore("additions", createSiblingMenuManager);

      // Force an update because Eclipse hides empty menus now.
      //
      submenuManager.addMenuListener
        (new IMenuListener()
         {
           public void menuAboutToShow(IMenuManager menuManager)
           {
             menuManager.updateAll(true);
           }
         });

      validateAutomaticallyAction.setChecked(true);
      submenuManager.insertAfter("additions-end", validateAutomaticallyAction);
      addGlobalActions(submenuManager);
    }

    /**
     * This adds Separators to the tool bar.
     */
    @Override
    public void contributeToToolBar(IToolBarManager toolBarManager)
    {
      toolBarManager.add(new Separator("xsd-settings"));
      toolBarManager.add(new Separator("xsd-additions"));
    }

    /**
     * When the active editor changes, this remembers the change, and
     * registers with it as a selection provider.
     */
    @Override
    public void setActiveEditor(IEditorPart part)
    {
      super.setActiveEditor(part);
      activeEditorPart = part;

      // switch to the new selection provider
      if (selectionProvider != null)
      {
        selectionProvider.removeSelectionChangedListener(this);
      }
      selectionProvider = part.getSite().getSelectionProvider();
      selectionProvider.addSelectionChangedListener(this);

      // fake a selection changed event to update the menus
      if (selectionProvider.getSelection() != null)
        selectionChanged(new SelectionChangedEvent(selectionProvider, selectionProvider.getSelection()));

      if (part instanceof XSDEditor)
      {
        validateAutomaticallyAction.setChecked(((XSDEditor)part).isValidateAutomatically());
      }
    }

    /**
     * This implements {@link ISelectionChangedListener}, handling
     * SelectionChangedEvents by querying for the children and siblings that
     * can be added to the selected object and updating the menus
     * accordingly.
     */
    public void selectionChanged(SelectionChangedEvent event)
    {
      // remove any menu items for old selection
      if (createChildMenuManager != null)
      {
        depopulateManager(createChildMenuManager, createChildActions);
      }
      if (createSiblingMenuManager != null)
      {
        depopulateManager(createSiblingMenuManager, createSiblingActions);
      }

      // query new selection for appropriate new child/sibling descriptors...
      Collection<?> newChildDescriptors = Collections.emptyList();
      Collection<?> newSiblingDescriptors = Collections.emptyList();
      ISelection sel = event.getSelection();

      if (sel instanceof IStructuredSelection
          && ((IStructuredSelection) sel).size() == 1)
      {
        Object object = ((IStructuredSelection) sel).getFirstElement();
        EditingDomain domain =
          ((IEditingDomainProvider) activeEditorPart).getEditingDomain();

        newChildDescriptors = domain.getNewChildDescriptors(object, null);
        newSiblingDescriptors = domain.getNewChildDescriptors(domain.getParent(object), object);
      }

      // generate actions for selection, populate and redraw menu
      createChildActions = generateCreateChildActions(newChildDescriptors, sel);
      createSiblingActions = generateCreateSiblingActions(newSiblingDescriptors, sel);

      if (createChildMenuManager != null)
      {
        populateManager(createChildMenuManager, createChildActions, null);
        createChildMenuManager.update(true);
      }
      if (createSiblingMenuManager != null)
      {
        populateManager(createSiblingMenuManager, createSiblingActions, null);
        createSiblingMenuManager.update(true);
      }
    }

    /**
     * This generates a {@link CreateChildAction} for each object in
     * <code>descriptors</code>, and returns the collection of these actions.
     */
    protected Collection<IAction> generateCreateChildActions(Collection<?> descriptors, ISelection selection)
    {
      Collection<IAction> actions = new LinkedList<IAction>();
      for (Object descriptor : descriptors)
      {
        actions.add(new CreateChildAction(activeEditorPart, selection, descriptor));
      }
      return actions;
    }

    /**
     * This generates a {@link CreateSiblingAction} for each object in
     * <code>descriptors</code>, and returns the collection of these actions.
     */
    protected Collection<IAction> generateCreateSiblingActions(Collection<?> descriptors, ISelection selection)
    {
      Collection<IAction> actions = new LinkedList<IAction>();
      for (Object descriptor : descriptors)
      {
        actions.add(new CreateSiblingAction(activeEditorPart, selection, descriptor));
      }
      return actions;
    }

    /**
     * This populates the specified IContributionManager with
     * ActionContributionItems based on the IActions contained in
     * the actions collection, by inserting them before the specified
     * contribution item ID.  If ID is null, they are simply added.
     */
    protected void populateManager(IContributionManager manager, Collection<IAction> actions,  String ID)
    {
      for (IAction action : actions)
      {
        if (ID != null)
        {
          manager.insertBefore(ID, action);
        }
        else
        {
          manager.add(action);
        }
      }
    }

    /**
     * This removes from the specified IContributionManager all
     * ActionContributionItems based on the IActions contained in the
     * actions collection.
     */
    protected void depopulateManager(IContributionManager manager, Collection<IAction> actions)
    {
      IContributionItem[] item = manager.getItems();
      for (int i = 0; i < item.length; i++)
      {
        // look into SubContributionItems
        IContributionItem curItem = item[i];
        while (curItem instanceof SubContributionItem)
        {
          curItem = ((SubContributionItem) curItem).getInnerItem();
        }

        // delete ActionContributionItems with matching action
        if (curItem instanceof ActionContributionItem)
        {
          IAction action = ((ActionContributionItem) curItem).getAction();
          if (actions.contains(action))
          {
            manager.remove(curItem);
          }
        }
      }
    }

    /**
     * This populates the pop-up menu before it appears.
     */
    @Override
    public void menuAboutToShow(IMenuManager menuManager)
    {
      super.menuAboutToShow(menuManager);

      MenuManager submenuManager = new MenuManager(XSDEditorPlugin.INSTANCE.getString("_UI_CreateChild_menu_item"));
      populateManager(submenuManager, createChildActions, null);
      menuManager.insertBefore("edit", submenuManager);
 
      submenuManager = new MenuManager(XSDEditorPlugin.INSTANCE.getString("_UI_CreateSibling_menu_item"));
      populateManager(submenuManager, createSiblingActions, null);
      menuManager.insertBefore("edit", submenuManager);
    }

    /**
     * This inserts global actions before the "additions-end" separator.
     */
    @Override
    protected void addGlobalActions(IMenuManager menuManager)
    {
      menuManager.insertAfter("additions-end", new Separator("ui-actions"));
      menuManager.insertAfter("ui-actions", showPropertiesViewAction);
  
      refreshViewerAction.setEnabled(refreshViewerAction.isEnabled());
      menuManager.insertAfter("ui-actions", refreshViewerAction);
  
      super.addGlobalActions(menuManager);
    }
  }

  /**
   * This returns the viewer as required by the {@link IViewerProvider} interface.
   */
  public Viewer getViewer()
  {
    return currentViewer;
  }

  /**
   * This creates a context menu for the viewer and adds a listener as well registering the menu for extension.
   */
  protected void createContextMenuFor(StructuredViewer viewer)
  {
    MenuManager contextMenu = new MenuManager("#PopUp");
    contextMenu.add(new Separator("additions"));
    contextMenu.setRemoveAllWhenShown(true);
    contextMenu.addMenuListener(this);
    Menu menu= contextMenu.createContextMenu(viewer.getControl());
    viewer.getControl().setMenu(menu);
    getSite().registerContextMenu(contextMenu, viewer);

    int dndOperations = DND.DROP_COPY | DND.DROP_MOVE | DND.DROP_LINK;
    Transfer[] transfers = new Transfer[] { LocalTransfer.getInstance() };
    viewer.addDragSupport(dndOperations, transfers, new ViewerDragAdapter(viewer));
    viewer.addDropSupport(dndOperations, transfers, new EditingDomainViewerDropAdapter(editingDomain, viewer));
  }


  /**
   * This is the method used by the framework to install your own controls.
   */
  @Override
  public void createPages()
  {
    createSourcePage();
    createSemanticsPage();
    createSyntaxPage();

    setActivePage(0);
    setCurrentViewer((Viewer)sourceViewer);
  }

  protected void createResource(String uri)
  {
    extendedCreateResource(uri);
  }

  protected void standardCreateResource(String uri)
  {

    // Load the resource through the editing domain.
    // This will creat a context and associate it with the resource set.
    //
    XSDResourceImpl xsdResource = (XSDResourceImpl)editingDomain.loadResource(uri);
    xsdSchema = xsdResource.getSchema();
  }

  protected void extendedCreateResource(String uri)
  {
    editingDomain.getResourceSet().getLoadOptions().put(XSDResourceImpl.XSD_TRACK_LOCATION, Boolean.TRUE);
    try
    {
      XSDResourceImpl xsdResource = (XSDResourceImpl)editingDomain.getResourceSet().createResource(URI.createURI(uri), XSDPackage.eCONTENT_TYPE);
      xsdResource.load(editingDomain.getResourceSet().getLoadOptions());
      xsdSchema = xsdResource.getSchema();
    }
    catch (Exception exception)
    {
      XSDEditorPlugin.INSTANCE.log(exception);
    }
  }

  protected void createModel()
  {
    // Do the work within an operation because this is a long running activity that modifies the workbench.
    //
    WorkspaceModifyOperation operation =
      new WorkspaceModifyOperation()
      {
        // This is the method that gets invoked when the operation runs.
        //
        @Override
        protected void execute(IProgressMonitor progressMonitor) throws CoreException
        {
          try
          {
            progressMonitor.beginTask("", 12);

            editingDomain.getResourceSet().getLoadOptions().put(XSDResourceImpl.XSD_PROGRESS_MONITOR, progressMonitor);
            createResource(EditUIUtil.getURI(getEditorInput()).toString());
            editingDomain.getResourceSet().getLoadOptions().remove(XSDResourceImpl.XSD_PROGRESS_MONITOR);

            progressMonitor.worked(1);
            progressMonitor.subTask(XSDEditorPlugin.INSTANCE.getString("_UI_Validating_message"));
            if (xsdSchema.getDiagnostics().isEmpty())
            {
              xsdSchema.validate();
            }

            if (determineEncoding() != null && getEditorInput() instanceof IFileEditorInput)
            {
              ((IFileEditorInput)getEditorInput()).getFile().setCharset(determineEncoding(), BasicMonitor.subProgress(progressMonitor, 2));
            }

            progressMonitor.worked(1);
            progressMonitor.subTask(XSDEditorPlugin.INSTANCE.getString("_UI_ReportingErrors_message"));
          }
          finally
          {
            progressMonitor.done();
          }
        }
      };

    try
    {
      // This runs the operation, and shows progress.
      // (It appears to be a bad thing to fork this onto another thread.)
      //
      new ProgressMonitorDialog(getSite().getShell()).run(false, false, operation);
    }
    catch (Exception exception)
    {
      XSDEditorPlugin.INSTANCE.log(exception);
    }
  }

  protected void handleSourceCaretPosition()
  {
    int offset = sourceViewer.getTextWidget().getCaretOffset();
    Element element = xsdSchema.getElement();
    if (element != null)
    {
      IDocument document = sourceViewer.getDocument();
      int line = 0;
      int lineOffset = 0;
      try
      {
        line = document.getLineOfOffset(offset);
        lineOffset = document.getLineOffset(line);
      }
      catch (BadLocationException exception)
      {
        // Ignore
      }
      int column = offset - lineOffset;
      // System.out.println("[" + line + "," + column + "]");

      Element bestElement = findBestElement(element, line + 1, column + 1);
      if (bestElement != null)
      {
        handleSelectedNodes(Collections.singleton(bestElement));
      }
    }
  }

  public Element findBestElement(Element element, int line, int column)
  {
    int startLine = XSDParser.getStartLine(element);
    int startColumn = XSDParser.getStartColumn(element);
    int endLine = XSDParser.getEndLine(element);
    int endColumn = XSDParser.getEndColumn(element);

    Element candidate = null;
    if ((line == startLine ? column >= startColumn : line > startLine)  &&
          (line == endLine ? column <= endColumn : line < endLine))
    {
      candidate = element;
      for (Node child = element.getFirstChild(); child != null; child = child.getNextSibling())
      {
        if (child.getNodeType() == Node.ELEMENT_NODE)
        {
          Element childElement = (Element)child;
          Element betterCandidate = findBestElement(childElement, line, column);
          if (betterCandidate != null)
          {
            candidate = betterCandidate;
            break;
          }
        }
      }
    }
    return candidate;
  }


  public void handleSelectedNodes(Collection<? extends Node> nodes)
  {
    Collection<Object> selection = new ArrayList<Object>();
    for (Node node : nodes)
    {
      XSDConcreteComponent bestXSDConcreteComponent = xsdSchema.getCorrespondingComponent(node);
      if (bestXSDConcreteComponent != null)
      {
        boolean add = true;
        for (XSDConcreteComponent parent = bestXSDConcreteComponent;
             parent != null;
             parent = parent.getContainer())
        {
          if (selection.contains(parent))
          {
            add = false;
            break;
          }
        }
        if (add)
        {
          XSDConcreteComponent container = bestXSDConcreteComponent.getContainer();
          if (container instanceof XSDParticle || container instanceof XSDAttributeUse)
          {
            bestXSDConcreteComponent = container;
          }
          selection.add(bestXSDConcreteComponent);
        }
      }
    }
    if (!selection.isEmpty())
    {
      ISelection newSelection = new StructuredSelection(selection.toArray());
      if (contentOutlineViewer != null)
      {
        contentOutlineViewer.setSelection(newSelection, true);
      }
      setSelection(newSelection);
      handleContentOutlineSelectionForTextEditor(newSelection, false);
    }
  }

  protected void handleDocumentChange()
  {
    try
    {
      XSDParser xsdParser = new XSDParser(null);
      String documentContent = sourceViewer.getDocument().get();
      xsdParser.parseString(documentContent);
      xsdSchema.clearDiagnostics();
      xsdParser.setSchema(xsdSchema);
      if (validateAutomatically)
      {
        xsdSchema.validate();
        handleDiagnostics(null);
      }
    }
    catch (Exception exception)
    {
      XSDEditorPlugin.INSTANCE.log(exception);
    }
  }

  protected void createSourcePage()
  {
    try
    {
      // Create the SED Editor.
      //
      textEditor =
        new TextEditor()
        {
          @Override
          public ISourceViewer createSourceViewer(Composite parent, IVerticalRuler ruler, int styles)
          {
            final ISourceViewer result = super.createSourceViewer(parent, ruler, styles);
            result.getTextWidget().addMouseListener
              (new MouseAdapter()
               {
                 @Override
                public void mouseDown(MouseEvent event)
                 {
                   handleSourceCaretPosition();
                 }
               });
            result.getTextWidget().addKeyListener
              (new KeyAdapter()
               {
                 @Override
                public void keyPressed(KeyEvent event)
                 {
                   switch (event.keyCode)
                   {
                     case SWT.ARROW_UP:
                     case SWT.ARROW_DOWN:
                     case SWT.ARROW_LEFT:
                     case SWT.ARROW_RIGHT:
                     case SWT.PAGE_UP:
                     case SWT.PAGE_DOWN:
                     {
                       handleSourceCaretPosition();
                       break;
                     }
                   }
                 }
               });
            sourceViewer = result;
            return result;
          }
        };

      createModel();

      int pageIndex = addPage(textEditor, getEditorInput());

      handleDiagnostics(null);

      setPageText(pageIndex, XSDEditorPlugin.INSTANCE.getString("_UI_Source_title"));

      IDocument document = textEditor.getDocumentProvider().getDocument(textEditor.getEditorInput());

      document.addDocumentListener
        (new IDocumentListener()
         {
           protected Timer timer = new Timer();
           protected TimerTask timerTask;

           public void documentAboutToBeChanged(DocumentEvent documentEvent)
           {
             // Ingore
           }

           public void documentChanged(final DocumentEvent documentEvent)
           {
             try
             {
               // This is need for the Properties view.
               //
               // setSelection(StructuredSelection.EMPTY);

               if (timerTask != null)
               {
                 timerTask.cancel();
               }

               if (handledStructuredModelChange)
               {
                 handledStructuredModelChange = false;
                 handleDocumentChange();
               }
               else
               {
                 timerTask =
                   new TimerTask()
                   {
                     @Override
                    public void run()
                     {
                       getSite().getShell().getDisplay().asyncExec
                         (new Runnable()
                          {
                            public void run()
                            {
                              handleDocumentChange();
                            }
                          });
                     }
                   };

                 timer.schedule(timerTask, 1000);
               }
             }
             catch (Exception exception)
             {
               XSDEditorPlugin.INSTANCE.log(exception);
             }
           }
         });
    }
    catch (Exception exception)
    {
      XSDEditorPlugin.INSTANCE.log(exception);
    }
  }

  protected void createSemanticsPage()
  {
    // Create a page for the selection tree view.
    //
    {
      ViewerPane viewerPane =
        new ViewerPane(getSite().getPage(), XSDEditor.this)
        {
          @Override
          public Viewer createViewer(Composite composite)
          {
            Tree tree = new Tree(composite, SWT.MULTI);
            TreeViewer newTreeViewer = new TreeViewer(tree);
            return newTreeViewer;
          }
          @Override
          public void requestActivation()
          {
            super.requestActivation();
            setCurrentViewerPane(this);
          }
        };
      viewerPane.createControl(getContainer());

      semanticSelectionViewer = (TreeViewer)viewerPane.getViewer();
      semanticSelectionViewer.setContentProvider(new AdapterFactoryContentProvider(semanticAdapterFactory));
      semanticSelectionViewer.setLabelProvider(new AdapterFactoryLabelProvider(semanticAdapterFactory));
      semanticSelectionViewer.setAutoExpandLevel(2);

      semanticSelectionViewer.addSelectionChangedListener
        (new ISelectionChangedListener()
         {
           // This just notifies those things that are affected by the section.
           //
           public void selectionChanged(SelectionChangedEvent selectionChangedEvent)
           {
             if (currentViewer == semanticSelectionViewer && contentOutlineViewer != null)
             {
               contentOutlineViewer.setSelection(selectionChangedEvent.getSelection(), true);
             }
           }
         });

      semanticSelectionViewer.setInput(new ItemProvider(Collections.singleton(xsdSchema)));
      viewerPane.setTitle(xsdSchema);

      new AdapterFactoryTreeEditor(semanticSelectionViewer.getTree(), semanticAdapterFactory);

      createContextMenuFor(semanticSelectionViewer);
      int pageIndex = addPage(viewerPane.getControl());
      setPageText(pageIndex, XSDEditorPlugin.INSTANCE.getString("_UI_Semantics_title"));
    }
  }

  protected void createSyntaxPage()
  {
    // Create a page for the selection tree view.
    //
    {
      ViewerPane viewerPane =
        new ViewerPane(getSite().getPage(), XSDEditor.this)
        {
          @Override
          public Viewer createViewer(Composite composite)
          {
            Tree tree = new Tree(composite, SWT.MULTI);
            TreeViewer newTreeViewer = new TreeViewer(tree);
            return newTreeViewer;
          }
          @Override
          public void requestActivation()
          {
            super.requestActivation();
            setCurrentViewerPane(this);
          }
        };
      viewerPane.createControl(getContainer());

      syntacticSelectionViewer = (TreeViewer)viewerPane.getViewer();
      syntacticSelectionViewer.setContentProvider(new AdapterFactoryContentProvider(syntacticAdapterFactory));
      syntacticSelectionViewer.setLabelProvider(new AdapterFactoryLabelProvider(syntacticAdapterFactory));
      syntacticSelectionViewer.setAutoExpandLevel(2);

      syntacticSelectionViewer.setInput(new ItemProvider(Collections.singleton(xsdSchema)));
      viewerPane.setTitle(xsdSchema);

      new AdapterFactoryTreeEditor(syntacticSelectionViewer.getTree(), syntacticAdapterFactory);

      createContextMenuFor(syntacticSelectionViewer);
      int pageIndex = addPage(viewerPane.getControl());
      setPageText(pageIndex, XSDEditorPlugin.INSTANCE.getString("_UI_Syntax_title"));
    }
  }

  protected void initializeMarkerPosition(IMarker marker, XSDDiagnostic xsdDiagnostic) throws CoreException
  {
    Node node = xsdDiagnostic.getNode();
    if (node != null && node.getNodeType() == Node.ATTRIBUTE_NODE)
    {
      node = ((Attr)node).getOwnerElement();
    }
    if (node != null && /* !xsdDiagnostic.isSetLine() && */ XSDParser.getUserData(node) != null)
    {
      int startLine = XSDParser.getStartLine(node) - 1;
      int startColumn = XSDParser.getStartColumn(node);
      int endLine = XSDParser.getEndLine(node) - 1;
      int endColumn = XSDParser.getEndColumn(node);

      marker.setAttribute(IMarker.LINE_NUMBER, startLine);

      try
      {
        IDocument document = textEditor.getDocumentProvider().getDocument(textEditor.getEditorInput());
        marker.setAttribute(IMarker.CHAR_START, document.getLineOffset(startLine) + startColumn - 1);
        marker.setAttribute(IMarker.CHAR_END, document.getLineOffset(endLine) + endColumn - 1);
      }
      catch (BadLocationException exception)
      {
        // Ignore
      }
    }
    else
    {
      marker.setAttribute(IMarker.LINE_NUMBER, xsdDiagnostic.getLine());
    }
  }

  protected void handleDiagnostics(IProgressMonitor progressMonitor)
  {
    if (progressMonitor == null)
    {
      // Do the work within an operation because this is a long running activity that modifies the workbench.
      //
      IWorkspaceRunnable operation =
        new IWorkspaceRunnable()
        {
          // This is the method that gets invoked when the operation runs.
          //
          public void run(IProgressMonitor localProgressMonitor) throws CoreException
          {
            handleDiagnostics(localProgressMonitor);
          }
        };

      try
      {
        ResourcesPlugin.getWorkspace().run(operation, new NullProgressMonitor());
        // getSite().getWorkbenchWindow().run(false, false, operation);
      }
      catch (Exception exception)
      {
        XSDEditorPlugin.INSTANCE.log(exception);
      }
    }
    else
    {
      XSDConcreteComponent newSelection = null;
      if (getEditorInput() instanceof IFileEditorInput)
      {
        try
        {
          // I assume that the input is a file object.
          //
          IFileEditorInput modelFile = (IFileEditorInput)getEditorInput();
          IFile file = modelFile.getFile();
  
          IMarker[] markers = file.findMarkers(IMarker.PROBLEM, true, IResource.DEPTH_ZERO);
          Collection<IMarker> deletableMarkers = new ArrayList<IMarker>(Arrays.asList(markers));
  
          if (validateAutomatically)
          {
            for (XSDDiagnostic xsdDiagnostic : xsdSchema.getAllDiagnostics())
            {
              String uriReferencePath = xsdSchema.eResource().getURIFragment(xsdDiagnostic);
  
              IMarker marker = null;
              for (int i = 0; i < markers.length; ++i)
              {
                if (markers[i].getAttribute(XSDDiagnostic.URI_FRAGMENT_ATTRIBUTE, "").equals(uriReferencePath))
                {
                  marker = markers[i];
                  deletableMarkers.remove(marker);
                  break;
                }
              }
  
              if (marker == null)
              {
                marker = file.createMarker(XSDDiagnostic.MARKER);
                marker.setAttribute(XSDDiagnostic.URI_FRAGMENT_ATTRIBUTE, uriReferencePath);
              }
  
              initializeMarkerPosition(marker, xsdDiagnostic);
  
              marker.setAttribute(IMarker.MESSAGE, xsdDiagnostic.getMessage());
  
              switch (xsdDiagnostic.getSeverity().getValue())
              {
                case XSDDiagnosticSeverity.FATAL:
                case XSDDiagnosticSeverity.ERROR:
                {
                  if (newSelection == null)
                  {
                    newSelection = xsdDiagnostic.getPrimaryComponent();
                  }
                  marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
                  break;
                }
                case XSDDiagnosticSeverity.WARNING:
                {
                  marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_WARNING);
                  break;
                }
                case XSDDiagnosticSeverity.INFORMATION:
                {
                  marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_INFO);
                  break;
                }
              }
            }
          }
  
          for (IMarker marker : deletableMarkers)
          {
            marker.delete();
          }
        }
        catch (Exception exception)
        {
          XSDEditorPlugin.INSTANCE.log(exception);
        }
      }

      // This will refresh the status.
      //
      if (editorSelection != null)
      {
        setSelection(editorSelection);
      }
      // This is the startup case.
      //
      else if (newSelection != null)
      {
        final IStructuredSelection errorSelection = new StructuredSelection(newSelection);
        getSite().getShell().getDisplay().asyncExec
          (new Runnable()
           {
             public void run()
             {
               if (contentOutlineViewer != null)
               {
                 contentOutlineViewer.setSelection(errorSelection, true);
               }
               if (sourceViewer != null)
               {
                 handleContentOutlineSelectionForTextEditor(errorSelection, true);
               }
               setSelection(errorSelection);
               handleSourceCaretPosition();
             }
           });
      }
    }
  }

  /**
   * This is used to track the active viewer.
   */
  @Override
  protected void pageChange(int pageIndex)
  {
    super.pageChange(pageIndex);

    if (pageIndex == 0)
    {
      setCurrentViewerPane(null);
      setCurrentViewer((Viewer)sourceViewer);
    }

    if (contentOutlinePage != null)
    {
      handleContentOutlineSelection(contentOutlinePage.getSelection());
    }
  }

  /**
   * This is how the framework determines which interfaces we implement.
   */
  @SuppressWarnings({ "rawtypes", "unchecked" })
  @Override
  public Object getAdapter(Class key)
  {
    if (key.equals(IContentOutlinePage.class))
    {
      return getContentOutlinePage();
    }
    else if (key.equals(IPropertySheetPage.class))
    {
      return getPropertySheetPage();
    }
    else
    {
      return textEditor.getAdapter(key);
    }
  }

  /**
   * This is a utility function to resolve a component.
   */
  public static XSDConcreteComponent getResolvedObject(XSDConcreteComponent xsdConcreteComponent)
  {
    XSDConcreteComponent result =
      (XSDConcreteComponent)new XSDSwitch<Object>()
      {
        @Override
        public Object caseXSDAttributeUse(XSDAttributeUse xsdAttributeUse)
        {
          return xsdAttributeUse.getAttributeDeclaration().getResolvedAttributeDeclaration();
        }
        @Override
        public Object caseXSDAttributeDeclaration(XSDAttributeDeclaration xsdAttributeDeclaration)
        {
          return xsdAttributeDeclaration.getResolvedAttributeDeclaration();
        }
        @Override
        public Object caseXSDAttributeGroupDefinition(XSDAttributeGroupDefinition xsdAttributeGroupDefinition)
        {
          return xsdAttributeGroupDefinition.getResolvedAttributeGroupDefinition();
        }
        @Override
        public Object caseXSDElementDeclaration(XSDElementDeclaration xsdElementDeclaration)
        {
          return xsdElementDeclaration.getResolvedElementDeclaration();
        }
        @Override
        public Object caseXSDModelGroupDefinition(XSDModelGroupDefinition xsdModelGroupDefinition)
        {
          return xsdModelGroupDefinition.getResolvedModelGroupDefinition();
        }
        @Override
        public Object caseXSDParticle(XSDParticle xsdParticle)
        {
          Object resolvedObject = getResolvedObject(xsdParticle.getContent());
          if (resolvedObject instanceof XSDModelGroup)
          {
            return xsdParticle;
          }
          else
          {
            return resolvedObject;
          }
        }
      }.doSwitch(xsdConcreteComponent);

    return result == null ? xsdConcreteComponent : result;
  }

  /**
   * This accesses a cached version of the content outliner.
   */
  public IContentOutlinePage getContentOutlinePage()
  {
    if (contentOutlinePage == null)
    {
      // The content outline is just a tree.
      //
      class MyContentOutlinePage extends ContentOutlinePage
      {
        @Override
        public void createControl(Composite parent)
        {
          super.createControl(parent);
          contentOutlineViewer = getTreeViewer();
          contentOutlineViewer.addSelectionChangedListener(this);
          contentOutlineViewer.setAutoExpandLevel(2);

          selectNextDiagnosticsAction = new SelectDiagnosticAction(true, contentOutlineViewer);
          selectPreviousDiagnosticsAction = new SelectDiagnosticAction(false, contentOutlineViewer);

          selectNextUseAction = new SelectUseAction(true, contentOutlineViewer);
          selectPreviousUseAction = new SelectUseAction(false, contentOutlineViewer);

          contentOutlineViewer.getTree().addMouseListener
            (new MouseAdapter()
             {
               @Override
              public void mouseDoubleClick(MouseEvent event)
               {
                 // Do fancy navigation selections when double clicking.
                 //
                 IStructuredSelection selection = (IStructuredSelection)contentOutlineViewer.getSelection();
                 for (Object object :  selection.toList())
                 {
                   XSDConcreteComponent xsdConcreteComponent = (XSDConcreteComponent)object;
                   Object resolvedObject = getResolvedObject(xsdConcreteComponent);
                   if (xsdConcreteComponent != resolvedObject)
                   {
                     contentOutlineViewer.setSelection(new StructuredSelection(new Object [] {resolvedObject}), true);
                     break;
                   }
                   else if (xsdConcreteComponent instanceof XSDAttributeDeclaration)
                   {
                     XSDAttributeDeclaration xsdAttributeDeclaration = (XSDAttributeDeclaration)xsdConcreteComponent;
                     XSDSimpleTypeDefinition typeDefinition = xsdAttributeDeclaration.getTypeDefinition();
                     if (typeDefinition != null && typeDefinition.getSchema() == xsdAttributeDeclaration.getSchema())
                     {
                       contentOutlineViewer.setSelection(new StructuredSelection(new Object [] {typeDefinition}), true);
                       break;
                     }
                   }
                   else if (xsdConcreteComponent instanceof XSDElementDeclaration)
                   {
                     XSDElementDeclaration xsdElementDeclaration = (XSDElementDeclaration)xsdConcreteComponent;
                     XSDTypeDefinition typeDefinition = xsdElementDeclaration.getTypeDefinition();
                     if (typeDefinition != null && typeDefinition.getSchema() == xsdElementDeclaration.getSchema())
                     {
                       contentOutlineViewer.setSelection(new StructuredSelection(new Object [] {typeDefinition}), true);
                       break;
                     }
                   }
                   else if (xsdConcreteComponent instanceof XSDSimpleTypeDefinition)
                   {
                     XSDSimpleTypeDefinition xsdSimpleTypeDefinition = (XSDSimpleTypeDefinition)xsdConcreteComponent;
                     XSDSimpleTypeDefinition baseTypeDefinition = xsdSimpleTypeDefinition.getBaseTypeDefinition();
                     if (baseTypeDefinition != null && baseTypeDefinition.getSchema() == xsdSimpleTypeDefinition.getSchema())
                     {
                       contentOutlineViewer.setSelection(new StructuredSelection(new Object [] {baseTypeDefinition}), true);
                       break;
                     }
                     XSDSimpleTypeDefinition itemTypeDefinition = xsdSimpleTypeDefinition.getItemTypeDefinition();
                     if (itemTypeDefinition != null && itemTypeDefinition.getSchema() == xsdSimpleTypeDefinition.getSchema())
                     {
                       contentOutlineViewer.setSelection(new StructuredSelection(new Object [] {itemTypeDefinition}), true);
                       break;
                     }
                     List<?> memberTypeDefinitions = xsdSimpleTypeDefinition.getMemberTypeDefinitions();
                     if (!memberTypeDefinitions.isEmpty())
                     {
                       contentOutlineViewer.setSelection(new StructuredSelection(memberTypeDefinitions.toArray()), true);
                       break;
                     }
                   }
                   else if (xsdConcreteComponent instanceof XSDComplexTypeDefinition)
                   {
                     XSDComplexTypeDefinition xsdComplexTypeDefinition = (XSDComplexTypeDefinition)xsdConcreteComponent;
                     XSDTypeDefinition baseTypeDefinition = xsdComplexTypeDefinition.getBaseTypeDefinition();
                     if (baseTypeDefinition != null && baseTypeDefinition.getSchema() == xsdComplexTypeDefinition.getSchema())
                     {
                       contentOutlineViewer.setSelection(new StructuredSelection(new Object [] {baseTypeDefinition}), true);
                       break;
                     }
                   }
                 }
               }
             });

          // Set up the tree viewer.
          //
          contentOutlineViewer.setContentProvider(new AdapterFactoryContentProvider(syntacticAdapterFactory));
          contentOutlineViewer.setLabelProvider(new AdapterFactoryLabelProvider(syntacticAdapterFactory));
          contentOutlineViewer.setInput(new ItemProvider(Collections.singleton(xsdSchema)));

          // Make sure our popups work.
          //
          createContextMenuFor(contentOutlineViewer);

          // Select the root object in the view.
          //
          ArrayList<Object> selection = new ArrayList<Object>();
          selection.add(xsdSchema);
          contentOutlineViewer.setSelection(new StructuredSelection(selection), true);

          // Listen to selection so that we can handle it is a special way.
          //
          this.addSelectionChangedListener
            (new ISelectionChangedListener()
             {
               // This ensures that we handle selections correctly.
               //
               public void selectionChanged(SelectionChangedEvent event)
               {
                 ISelection s = event.getSelection();
                 if (contentOutlineViewer == currentViewer)
                 {
                   handleContentOutlineSelection(s);
                 }
                 selectNextDiagnosticsAction.setCurrentObjects(((IStructuredSelection)s).toList());
                 selectPreviousDiagnosticsAction.setCurrentObjects(((IStructuredSelection)s).toList());

                 selectNextUseAction.setCurrentObjects(((IStructuredSelection)s).toList());
                 selectPreviousUseAction.setCurrentObjects(((IStructuredSelection)s).toList());
               }
             });
        }

        @Override
        public void setActionBars(IActionBars actionBars)
        {
          super.setActionBars(actionBars);

          contentOutlineStatusLineManager = actionBars.getStatusLineManager();

          actionBars.getToolBarManager().add(selectNextUseAction);
          actionBars.getToolBarManager().add(selectPreviousUseAction);

          actionBars.getToolBarManager().add(selectNextDiagnosticsAction);
          actionBars.getToolBarManager().add(selectPreviousDiagnosticsAction);


          actionBars.getMenuManager().add(selectNextDiagnosticsAction);
          actionBars.getMenuManager().add(selectPreviousDiagnosticsAction);

          actionBars.getMenuManager().add(selectNextUseAction);
          actionBars.getMenuManager().add(selectPreviousUseAction);

          getActionBarContributor().shareGlobalActions(this, actionBars);
        }
      }

      contentOutlinePage = new MyContentOutlinePage();

      // Listen to selection so that we can handle it is a special way.
      //
      contentOutlinePage.addSelectionChangedListener
        (new ISelectionChangedListener()
         {
           // This ensures that we handle selections correctly.
           //
           public void selectionChanged(SelectionChangedEvent event)
           {
             if (contentOutlineViewer == currentViewer)
             {
               handleContentOutlineSelection(event.getSelection());
             }
           }
         });
    }

    return contentOutlinePage;
  }

  /**
   * This accesses a cached version of the property sheet.
   */
  public IPropertySheetPage getPropertySheetPage()
  {
    if (propertySheetPage == null)
    {
      propertySheetPage =
        new ExtendedPropertySheetPage(editingDomain)
        {
          @Override
          public void makeContributions(IMenuManager menuManager, IToolBarManager toolBarManager, IStatusLineManager statusLineManager)
          {
            super.makeContributions(menuManager, toolBarManager, statusLineManager);
          }

          @Override
          public void setSelectionToViewer(List<?> selection)
          {
            XSDEditor.this.setSelectionToViewer(selection);
            XSDEditor.this.setFocus();
          }

          @Override
          public void setActionBars(IActionBars actionBars)
          {
            super.setActionBars(actionBars);
            getActionBarContributor().shareGlobalActions(this, actionBars);
          }
        };
      propertySheetPage.setPropertySourceProvider
        (new AdapterFactoryContentProvider(syntacticAdapterFactory)
         {
           @Override
          protected IPropertySource createPropertySource(Object object, IItemPropertySource itemPropertySource)
           {
             return
               new PropertySource(object, itemPropertySource)
               {
                 @Override
                protected IPropertyDescriptor createPropertyDescriptor(IItemPropertyDescriptor itemPropertyDescriptor)
                 {
                   return
                     new PropertyDescriptor(this.object, itemPropertyDescriptor)
                     {
                       @Override
                      public CellEditor createPropertyEditor(Composite composite)
                       {
                         if (!this.itemPropertyDescriptor.canSetProperty(this.object))
                         {
                           return null;
                         }

                         CellEditor result = null;

                         Object genericFeature = this.itemPropertyDescriptor.getFeature(this.object);
                         if (genericFeature instanceof EStructuralFeature)
                         {
                           EStructuralFeature feature = (EStructuralFeature)genericFeature;
                           EObject getEType = feature.getEType();
                           if (getEType == ecorePackage.getEBoolean())
                           {
                             Collection<?> choiceOfValues = this.itemPropertyDescriptor.getChoiceOfValues(this.object);
                             if (choiceOfValues != null)
                             {
                               result =
                                 new ExtendedComboBoxCellEditor
                                   (composite, new ArrayList<Object>(choiceOfValues), getLabelProvider(), true);
                             }
                           }
                         }
                         if (result == null)
                         {
                           result = super.createPropertyEditor(composite);
                         }
                         return result;
                       }
                     };
                 }
               };
           }
         });
    }

    return propertySheetPage;
  }

  /**
   * This deals with how we want selection in the outliner to affect the other views.
   */
  public void handleContentOutlineSelection(ISelection selection)
  {
    if ((currentViewerPane != null || getActivePage() == 0) && !selection.isEmpty() && selection instanceof IStructuredSelection)
    {
      if (getActivePage() == 0)
      {
        handleContentOutlineSelectionForTextEditor(selection, true);
      }
      else if (currentViewerPane.getViewer() == syntacticSelectionViewer)
      {
        // Set the selection to the widget.
        //
        syntacticSelectionViewer.setSelection(selection);
      }
      else if (currentViewerPane.getViewer() == semanticSelectionViewer)
      {
        ArrayList<Object> selectionList = new ArrayList<Object>();
        for (Object object : ((IStructuredSelection)selection).toList())
        {
          selectionList.add(getResolvedObject((XSDConcreteComponent)object));
        }

        // Set the selection to the widget.
        //
        semanticSelectionViewer.setSelection(new StructuredSelection(selectionList));
      }
    }
  }

  /**
   * This deals with how we want selection in the outliner to affect the text editor.
   */
  public void handleContentOutlineSelectionForTextEditor(ISelection selection, boolean reveal)
  {
    XSDConcreteComponent xsdConcreteComponent = (XSDConcreteComponent)((IStructuredSelection)selection).iterator().next();
    if (xsdConcreteComponent instanceof XSDParticle)
    {
      XSDParticle xsdParticle = (XSDParticle)xsdConcreteComponent;
      XSDConcreteComponent content = xsdParticle.getContent();
      if (content != null)
      {
        xsdConcreteComponent = content;
      }
    }

    Element element = xsdConcreteComponent.getElement();
    if (element != null)
    {
      try
      {
        IDocument document = textEditor.getDocumentProvider().getDocument(textEditor.getEditorInput());
        int startLine = XSDParser.getStartLine(element);
        int startColumn = XSDParser.getStartColumn(element);
        int endLine = XSDParser.getEndLine(element);
        int endColumn = XSDParser.getEndColumn(element);

        int startOffset = document.getLineOffset(startLine - 1);
        startOffset += startColumn - 1;
        int endOffset = document.getLineOffset(endLine - 1);
        endOffset += endColumn - 1;
        if (startLine == endLine)
        {
          textEditor.setHighlightRange(startOffset, endOffset - startOffset, false);
          if (reveal)
          {
            textEditor.selectAndReveal(startOffset, endOffset - startOffset);
          }
        }
        else
        {
          textEditor.setHighlightRange(startOffset, endOffset - startOffset, reveal);
        }
      }
      catch (Exception exception)
      {
        XSDEditorPlugin.INSTANCE.log(exception);
      }
    }
  }

  /**
   * This is for implementing {@link IEditorPart} and simply tests the command stack.
   */
  @Override
  public boolean isDirty()
  {
    return ((BasicCommandStack)editingDomain.getCommandStack()).isSaveNeeded() || textEditor != null && textEditor.isDirty();
  }

  /**
   * This is for implementing {@link IEditorPart} and simply saves the model file.
   */
  @Override
  public void doSave(IProgressMonitor progressMonitor)
  {
    // Do the work within an operation because this is a long running activity that modifies the workbench.
    //
    WorkspaceModifyOperation operation =
      new WorkspaceModifyOperation()
      {
        // This is the method that gets invoked when the operation runs.
        //
        @Override
        protected void execute(IProgressMonitor monitor) throws CoreException
        {
          try
          {
            // Save the resource to the file system.
            //
            xsdSchema.eResource().save(Collections.EMPTY_MAP);
          }
          catch (Exception exception)
          {
            XSDEditorPlugin.INSTANCE.log(exception);
          }
        }
      };

    try
    {
      // This runs the operation, and shows progress.
      // (It appears to be a bad thing to fork this onto another thread.)
      //
      new ProgressMonitorDialog(getSite().getShell()).run(false, false, operation);

      // Refresh the necessary state.
      //
      ((BasicCommandStack)editingDomain.getCommandStack()).saveIsDone();
      textEditor.doRevertToSaved();
      firePropertyChange(IEditorPart.PROP_DIRTY);
    }
    catch (Exception exception)
    {
      // Something went wrong that shouldn't.
      //
      XSDEditorPlugin.INSTANCE.log(exception);
    }
  }

  /**
   * This always returns false because it is not current supported.
   */
  @Override
  public boolean isSaveAsAllowed()
  {
    return true;
  }

  /**
   * This also changes the editor's input.
   */
  @Override
  public void doSaveAs()
  {
    SaveAsDialog saveAsDialog = new SaveAsDialog(getSite().getShell());
    saveAsDialog.open();
    IPath path = saveAsDialog.getResult();
    if (path != null)
    {
      IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
      if (file != null)
      {
        xsdSchema.eResource().setURI(URI.createPlatformResourceURI(file.getFullPath().toString(), true));
        IFileEditorInput modelFile = new FileEditorInput(file);
        setInput(modelFile);
        setPartName(file.getName());
        doSave(getActionBars().getStatusLineManager().getProgressMonitor());
      }
    }
  }

  public void gotoMarker(IMarker marker)
  {
    try
    {
/*
      if (marker.getType().equals(XSDDiagnostic.MARKER) && xsdSchema != null)
      {
        XSDDiagnostic xsdDiagnostic =
          xsdSchema.getDiagnosticForURIReferencePath(marker.getAttribute(XSDDiagnostic.URI_FRAGMENT_ATTRIBUTE, "/0/"));
      }
*/
      setActivePage(0);
      ((IGotoMarker)textEditor.getAdapter(IGotoMarker.class)).gotoMarker(marker);
    }
    catch (Exception exception)
    {
      XSDEditorPlugin.INSTANCE.log(exception);
    }
  }

  /**
   * This is called during startup.
   */
  @Override
  public void init(IEditorSite site, IEditorInput editorInput) throws PartInitException
  {
    setSite(site);
    setInput(editorInput);
    setPartName(editorInput.getName());
    site.setSelectionProvider(new MultiPageSelectionProvider(this));
    site.getPage().addPartListener(partListener);
  }

  @Override
  public void setFocus()
  {
    if (currentViewerPane != null)
    {
      currentViewerPane.setFocus();
    }
    else
    {
      getControl(getActivePage()).setFocus();
    }
  }

  /**
   * This implements {@link org.eclipse.jface.viewers.ISelectionProvider}.
   */
  public void addSelectionChangedListener(ISelectionChangedListener listener)
  {
    selectionChangedListeners.add(listener);
  }

  /**
   * This implements {@link org.eclipse.jface.viewers.ISelectionProvider}.
   */
  public void removeSelectionChangedListener(ISelectionChangedListener listener)
  {
    selectionChangedListeners.remove(listener);
  }

  /**
   * This implements {@link org.eclipse.jface.viewers.ISelectionProvider} to return this editor's overall selection.
   */
  public ISelection getSelection()
  {
    return editorSelection;
  }

  /**
   * This implements {@link org.eclipse.jface.viewers.ISelectionProvider} to set this editor's overall selection.
   * Calling this result will notify the listeners.
   */
  public void setSelection(ISelection selection)
  {
    editorSelection = selection;

    SelectionChangedEvent selectionChangedEvent = new SelectionChangedEvent(this, selection);
    ((MultiPageSelectionProvider)getSite().getSelectionProvider()).fireSelectionChanged(selectionChangedEvent);
    for (ISelectionChangedListener listener : selectionChangedListeners)
    {
      listener.selectionChanged(selectionChangedEvent);
    }

    setStatusLineManager(selection);
  }

  /**
   *  This shows the selection on the status line.
   */
  public void setStatusLineManager(ISelection selection)
  {
    IStatusLineManager statusLineManager = currentViewer != null && currentViewer == contentOutlineViewer ?
      contentOutlineStatusLineManager : getActionBars().getStatusLineManager();

    if (statusLineManager != null)
    {
      if (selection instanceof IStructuredSelection)
      {
        Collection<?> collection = ((IStructuredSelection)selection).toList();
        switch (collection.size())
        {
          case 0:
          {
            statusLineManager.setMessage(XSDEditorPlugin.INSTANCE.getString("_UI_NoObjectSelected"));
            break;
          }
          case 1:
          {
            Object object = collection.iterator().next();
            String text = new AdapterFactoryItemDelegator(syntacticAdapterFactory).getText(object);
            text = XSDEditorPlugin.INSTANCE.getString("_UI_SingleObjectSelected", new Object [] { text });
            if (object instanceof XSDConcreteComponent)
            {
              XSDConcreteComponent xsdConcreteComponent = (XSDConcreteComponent)object;
              if (!xsdConcreteComponent.getDiagnostics().isEmpty())
              {
                text = (xsdConcreteComponent.getDiagnostics().get(0)).getMessage();
              }
            }

            statusLineManager.setMessage(text);
            break;
          }
          default:
          {
            statusLineManager.setMessage
              (XSDEditorPlugin.INSTANCE.getString("_UI_MultiObjectSelected", new Object [] { Integer.toString(collection.size()) }));
            break;
          }
        }
      }
      else
      {
        statusLineManager.setMessage("");
      }
    }
  }

  /**
   * This implements {@link org.eclipse.jface.action.IMenuListener} to help fill the context menus with contributions from the Edit menu.
   */
  public void menuAboutToShow(IMenuManager menuManager)
  {
    ((IMenuListener)getEditorSite().getActionBarContributor()).menuAboutToShow(menuManager);
  }

  /**
   * This convenience method provides typed access to the contributor.
   */
  public EditingDomainActionBarContributor getActionBarContributor()
  {
    return (EditingDomainActionBarContributor)getEditorSite().getActionBarContributor();
  }

  /**
   * This convenience method provides access to the actionbars.
   */
  public IActionBars getActionBars()
  {
    return getActionBarContributor().getActionBars();
  }

  /**
   * This is called when the editor is disposed.
   */
  @Override
  public void dispose()
  {
    super.dispose();
    getSite().getPage().removePartListener(partListener);
    ((IDisposable)semanticAdapterFactory).dispose();
    ((IDisposable)syntacticAdapterFactory).dispose();
  }

  protected boolean validateAutomatically = true;
  public void setValidateAutomatically(boolean validateAutomatically)
  {
    this.validateAutomatically = validateAutomatically;
    if (validateAutomatically)
    {
      handleDocumentChange();
    }
    else
    {
      handleDiagnostics(null);
    }
  }

  public boolean isValidateAutomatically()
  {
    return validateAutomatically;
  }

  /**
   * This is the base action for the outline actions.
   */
  class SelectObjectAction extends Action
  {
    protected Collection<?> objectsToSelect;
    protected StructuredViewer structuredViewer;

    public SelectObjectAction(StructuredViewer structuredViewer, String text, ImageDescriptor imageDescriptor)
    {
      super(text, imageDescriptor);
      this.structuredViewer = structuredViewer;
      setEnabled(false);
    }

    public void setObjectToSelect(Object objectToSelect)
    {
      setObjectsToSelect
        (objectToSelect != null ?
           Collections.singleton(objectToSelect) :
           Collections.EMPTY_LIST);
    }

    public void setObjectsToSelect(Collection<?> objectsToSelect)
    {
      this.objectsToSelect = new ArrayList<Object>(objectsToSelect);
      setEnabled(!objectsToSelect.isEmpty());
    }

    @Override
    public void run()
    {
      structuredViewer.setSelection(new StructuredSelection(objectsToSelect.toArray()), true);
    }
  }

  /**
   * This is used to implement the select next/previous unresolved component action.
   */
  class SelectDiagnosticAction extends SelectObjectAction
  {
    boolean isForward;
    public SelectDiagnosticAction(boolean isForward, StructuredViewer structuredViewer)
    {
      super
        (structuredViewer,
         isForward ?  "Select &Next Diagnosed Object" : "Select &Previous Diagnosed Object",
         ExtendedImageRegistry.INSTANCE.getImageDescriptor
           (XSDEditorPlugin.INSTANCE.getImage
             (isForward ? "full/elcl16/SelectNextDiagnosticObject" : "full/elcl16/SelectPreviousDiagnosticObject")));
      this.isForward = isForward;

      setHoverImageDescriptor
        (ExtendedImageRegistry.INSTANCE.getImageDescriptor
          (XSDEditorPlugin.INSTANCE.getImage
             (isForward ? "full/clcl16/SelectNextDiagnosticObject" : "full/clcl16/SelectPreviousDiagnosticObject")));

      setDisabledImageDescriptor
        (ExtendedImageRegistry.INSTANCE.getImageDescriptor
          (XSDEditorPlugin.INSTANCE.getImage
             (isForward ? "full/dlcl16/SelectNextDiagnosticObject" : "full/dlcl16/SelectPreviousDiagnosticObject")));
    }

    public void updateAction()
    {
      setCurrentObjects(((IStructuredSelection)structuredViewer.getSelection()).toList());
    }

    public void setCurrentObjects(List<?> objects)
    {
      XSDConcreteComponent result = null;

      boolean isStarted = false;
      for (TreeIterator<?> tree = editingDomain.treeIterator(xsdSchema); tree.hasNext(); )
      {
        XSDConcreteComponent xsdConcreteComponent = (XSDConcreteComponent)tree.next();
        if (!isForward && objects.contains(xsdConcreteComponent))
        {
          break;
        }
        else if (isStarted || !isForward)
        {
          if (!xsdConcreteComponent.getDiagnostics().isEmpty() ||
                 xsdConcreteComponent instanceof XSDParticle &&
                   !((XSDParticle)xsdConcreteComponent).getContent().getDiagnostics().isEmpty() ||
                 xsdConcreteComponent instanceof XSDAttributeUse &&
                   !((XSDAttributeUse)xsdConcreteComponent).getContent().getDiagnostics().isEmpty())
          {
            if (isStarted)
            {
              result = xsdConcreteComponent;
              break;
            }
            else
            {
              result = xsdConcreteComponent;
            }
          }
        }
        else if (objects.contains(xsdConcreteComponent))
        {
          isStarted = true;
        }
      }

      setObjectToSelect(result);
    }
  }

  /**
   * This is used to implement the select next/previous component use action.
   */
  class SelectUseAction extends SelectObjectAction
  {
    boolean isForward;
    public SelectUseAction(boolean isForward, StructuredViewer structuredViewer)
    {
      super
        (structuredViewer,
         isForward ?  "Select &Next Use" : "Select &Previous Use",
         ExtendedImageRegistry.INSTANCE.getImageDescriptor
           (XSDEditorPlugin.INSTANCE.getImage
             (isForward ? "full/elcl16/SelectNextUseObject" : "full/elcl16/SelectPreviousUseObject")));
      this.isForward = isForward;

      setHoverImageDescriptor
        (ExtendedImageRegistry.INSTANCE.getImageDescriptor
          (XSDEditorPlugin.INSTANCE.getImage
             (isForward ? "full/clcl16/SelectNextUseObject" : "full/clcl16/SelectPreviousUseObject")));
      setDisabledImageDescriptor
        (ExtendedImageRegistry.INSTANCE.getImageDescriptor
          (XSDEditorPlugin.INSTANCE.getImage
             (isForward ? "full/dlcl16/SelectNextUseObject" : "full/dlcl16/SelectPreviousUseObject")));
    }

    public void updateAction()
    {
      setCurrentObjects(((IStructuredSelection)structuredViewer.getSelection()).toList());
    }

    public void setCurrentObjects(List<?> objects)
    {
      XSDConcreteComponent result = null;

      final List<Object> resolvedObjects = new ArrayList<Object>();
      for (Object object : objects)
      {
        XSDConcreteComponent xsdConcreteComponent = (XSDConcreteComponent)object;
        XSDConcreteComponent resolvedObject = getResolvedObject(xsdConcreteComponent);
        if (resolvedObject != this)
        {
          resolvedObjects.add(resolvedObject);
        }
      }

      boolean isStarted = false;
      for (TreeIterator<?> tree = editingDomain.treeIterator(xsdSchema); tree.hasNext(); )
      {
        XSDConcreteComponent xsdConcreteComponent = (XSDConcreteComponent)tree.next();
        if (!isForward && objects.contains(xsdConcreteComponent))
        {
          break;
        }
        else if (isStarted || !isForward)
        {
          XSDConcreteComponent resolvedObject = getResolvedObject(xsdConcreteComponent);
          if (resolvedObjects.contains(resolvedObject))
          {
            if (isStarted)
            {
              result = xsdConcreteComponent;
              break;
            }
            else
            {
              result = xsdConcreteComponent;
            }
          }
        }
        else if (objects.contains(xsdConcreteComponent))
        {
          isStarted = true;
        }
      }

      setObjectToSelect(result);
    }
  }

  public static class GenericXMLResourceFactoryImpl extends XMLResourceFactoryImpl
  {
    public GenericXMLResourceFactoryImpl()
    {
      super();
    }

    @Override
    public Resource createResource(URI uri)
    {
      XMLResource result = new GenericXMLResourceImpl(uri);
      
      result.getDefaultSaveOptions().put(XMLResource.OPTION_EXTENDED_META_DATA, Boolean.TRUE);
      result.getDefaultLoadOptions().put(XMLResource.OPTION_EXTENDED_META_DATA, Boolean.TRUE);

      result.getDefaultLoadOptions().put(XMLResource.OPTION_USE_LEXICAL_HANDLER, Boolean.TRUE);

      result.getDefaultSaveOptions().put(XMLResource.OPTION_LINE_WIDTH, 80);

      result.getDefaultSaveOptions().put(XMLResource.OPTION_SCHEMA_LOCATION, Boolean.TRUE);
      return result;
    }
  }

  public static class GenericXMLResourceImpl extends XMLResourceImpl
  {
    protected XSDEcoreBuilder xsdEcoreBuilder;

    public GenericXMLResourceImpl(URI uri)
    {
      super(uri);
    }

    @Override
    protected XMLLoad createXMLLoad()
    {
      return 
        new XMLLoadImpl(createXMLHelper())
        {
          @Override
          protected DefaultHandler makeDefaultHandler()
          {
            return 
              new SAXXMLHandler(resource, helper, options)
              {
                @Override
               protected void handleTopLocations(String prefix, String name)
                {
                  if (urisToLocations != null)
                  {
                    xsdEcoreBuilder = new XSDEcoreBuilder(extendedMetaData);
                    Collection<Resource> resources = xsdEcoreBuilder.generateResources(urisToLocations.values());
                    resource.getResourceSet().getResources().addAll(resources);
                  }

                  // Ensure that anything can be handled, even if it's not recognized.
                  //
                  String namespaceURI = helper.getURI(prefix);
                  if (extendedMetaData.getPackage(namespaceURI) == null)
                  {
                    extendedMetaData.demandFeature(namespaceURI, name, true);
                  }
                }
              };
          }
        };
    }

/*
    public void doLoad(InputStream inputStream, final Map op) throws IOException
    {
      XMLLoad xmlStart =
        new XMLLoadImpl(createXMLHelper())
        {
          protected DefaultHandler makeDefaultHandler()
          {
            SAXXMLHandler saxXMLHandler =
              new SAXXMLHandler(resource, helper, op)
              {
                protected MyStack elementDeclarations = new MyStack();
                protected MyStack dfaStates = new MyStack();

                protected void createTopObject(String prefix, String name)
                {
                  String namespaceURI = helper.getURI(prefix);
                  for (int i = 0, size = attribs.getLength(); i < size; ++i)
                  {
                    String attributeName = attribs.getQName(i);
                    int index = attributeName.indexOf(":");
                    String attributeNamespaceURI = null;
                    String attributeLocalName = attributeName;
                    if (index != -1)
                    {
                      attributeNamespaceURI = helper.getURI(attributeName.substring(0, index));
                      attributeLocalName = attributeName.substring(index + 1);
                    }

                    if (XSDConstants.SCHEMA_INSTANCE_URI_2001.equals(attributeNamespaceURI) &&
                         (namespaceURI == null ? "noNamespaceSchemaLocation" : "schemaLocation").equals(attributeLocalName))
                    {
                      String schemaLocationHint = null;

                      if (namespaceURI == null)
                      {
                        schemaLocationHint = attribs.getValue(i);
                      }
                      else
                      {
                        for (StringTokenizer stringTokenizer = new StringTokenizer(attribs.getValue(i));
                             stringTokenizer.hasMoreTokens(); )
                        {
                          String namespaceURIHint = stringTokenizer.nextToken();
                          if (stringTokenizer.hasMoreTokens())
                          {
                            if (namespaceURIHint.equals(namespaceURI))
                            {
                              schemaLocationHint = stringTokenizer.nextToken();
                              break;
                            }
                            else
                            {
                              stringTokenizer.nextToken();
                            }
                          }
                          else
                          {
                            break;
                          }
                        }
                      }

                      if (schemaLocationHint != null)
                      {
                        URI uri = URI.createURI(schemaLocationHint);
                        if (resolve && uri.isRelative() && uri.hasRelativePath())
                        {
                          uri = uri.resolve(resourceURI);
                        }

                        xsdEcoreBuilder = new XSDEcoreBuilder();
                        Collection resources = xsdEcoreBuilder.generateResources(uri);
                        resource.getResourceSet().getResources().addAll(resources);
                      }
                    }
                  }

                  if (xsdEcoreBuilder == null)
                  {
                    error(new XMIException("Cannot resolve schema location",  getLocation(), getLineNumber(), getColumnNumber()));
                  }
                  else
                  {
                    XSDElementDeclaration xsdElementDeclaration =
                      xsdEcoreBuilder.getSchema().resolveElementDeclaration(namespaceURI, name);
                    EClass eClass = (EClass)xsdEcoreBuilder.getXSDComponentToEModelElementMap().get(xsdElementDeclaration);
                    if (eClass != null)
                    {
                      processTopObject(eClass.getEPackage().getEFactoryInstance().create(eClass));
                      elementDeclarations.push(xsdElementDeclaration);
                      XSDParticle xsdParticle = xsdElementDeclaration.getTypeDefinition().getComplexType();
                      if (xsdParticle != null)
                      {
                        dfaStates.push(xsdParticle.getDFA().getInitialState());
                      }
                      else
                      {
                        dfaStates.push(null);
                      }
                    }
                    else
                    {
                      error(new XMIException("Cannot resolve EClass ",  getLocation(), getLineNumber(), getColumnNumber()));
                    }
                  }
                }

                protected void processElement(String name, String prefix, String localName)
                {
                  if (isError())
                  {
                    types.push(ERROR_TYPE);
                  }
                  else
                  {
                    if (objects.isEmpty())
                    {
                      createTopObject(prefix, localName);

                    }
                    else
                    {
                      EObject peekObject = (EObject)objects.peek();
                      XSDParticle.DFA.State state = (XSDParticle.DFA.State)dfaStates.peek();
                      if (state == null)
                      {
                        error(new XMIException("Cannot contain content ",  getLocation(), getLineNumber(), getColumnNumber()));
                      }
                      else
                      {
                        XSDParticle.DFA.Transition transition = state.accept(helper.getURI(prefix), localName);
                        if (transition == null)
                        {
                          error(new XMIException("Not expecting this element ",  getLocation(), getLineNumber(), getColumnNumber()));
                        }
                        else
                        {
                          dfaStates.set(dfaStates.size() - 1, transition.getState());

                          XSDParticle transitionXSDParticle = transition.getParticle();
                          XSDTerm xsdTerm = transitionXSDParticle.getTerm();
                          XSDElementDeclaration xsdElementDeclaration = null;
                          if (xsdTerm instanceof XSDElementDeclaration)
                          {
                            xsdElementDeclaration =  (XSDElementDeclaration)xsdTerm;
                          }
                          else
                          {
                            xsdElementDeclaration = xsdEcoreBuilder.getSchema().resolveElementDeclaration(helper.getURI(prefix), name);
                          }

                          EClass eClass = (EClass)xsdEcoreBuilder.getXSDComponentToEModelElementMap().get(xsdElementDeclaration);
                          if (eClass != null)
                          {
                            EObject eObject = eClass.getEPackage().getEFactoryInstance().create(eClass);
                            ((EList)peekObject.eGet(peekObject.eClass().getEStructuralFeature("contents"))).add(eObject);

                            processObject(eObject);
                            elementDeclarations.push(xsdElementDeclaration);
                            XSDParticle xsdParticle = xsdElementDeclaration.getTypeDefinition().getComplexType();
                            if (xsdParticle != null)
                            {
                              dfaStates.push(xsdParticle.getDFA().getInitialState());
                            }
                            else
                            {
                              dfaStates.push(null);
                              XSDSimpleTypeDefinition xsdSimpleTypeDefinition = xsdElementDeclaration.getTypeDefinition().getSimpleType();
                              if (xsdSimpleTypeDefinition != null)
                              {
                                EStructuralFeature valueFeature = eClass.getEStructuralFeature("value");
                                if (valueFeature != null)
                                {
                                  text = new StringBuffer();
                                  types.set(types.size() - 1, valueFeature);
                                }
                              }
                            }
                          }
                          else
                          {
                            error(new XMIException("Cannot resolve EClass ",  getLocation(), getLineNumber(), getColumnNumber()));
                          }
                        }
                      }
                    }
                  }
                }

                public void endElement(String uri, String localName, String name)
                {
                  EObject topObject = (EObject)objects.pop();
                  elements.pop();
                  Object type = types.pop();

                  if (text != null)
                  {
                    EAttribute eAttribute = (EAttribute)type;
                    EDataType eDataType = eAttribute.getEAttributeType();
                    Object value = eDataType.getEPackage().getEFactoryInstance().createFromString(eDataType, text.toString());
                    topObject.eSet(eAttribute, value);
                    text = null;
                  }

                  XSDParticle.DFA.State state = (XSDParticle.DFA.State)dfaStates.pop();
                  if (state != null && !state.isAccepting())
                  {
                    error(new XMIException("Need more content ",  getLocation(), getLineNumber(), getColumnNumber()));
                  }
                  elementDeclarations.pop();
                }
              };

            return new SAXWrapper(saxXMLHandler);
          }
        };
      xmlStart.load(this, inputStream, op);
    }
*/
  }

  public static class GenericXMLLoadAction extends org.eclipse.ui.actions.ActionDelegate implements org.eclipse.ui.IActionDelegate
  {
    protected IFile file;
    protected IContainer container;

    public GenericXMLLoadAction()
    {
      super();
    }

    @Override
    public void run(IAction action)
    {
      if (file != null)
      {
        execute(file);
      }
      else 
      {
        execute(container);
      }
    }

    public void execute(IContainer container) 
    {
      try
      {
        IResource [] contents = container.members();
        for (int i = 0; i < contents.length; ++i)
        {
          IResource resource = contents[i];
          if (resource.getType() == IResource.FILE)
          {
            if ("xml".equals(resource.getLocation().getFileExtension()) && 
                  resource.getName().indexOf(".xml") == resource.getName().lastIndexOf(".xml"))
            {
              execute((IFile)resource);
            }
          }
          else
          {
            execute((IContainer)resource);
          }
        }
      }
      catch (CoreException exception)
      {
        XSDEditorPlugin.INSTANCE.log(exception);
        exception.printStackTrace();
      }

    }

    public void execute(IFile file)
    {
      System.err.println("Processing: " + file.getFullPath());
      ResourceSet resourceSet = new ResourceSetImpl();
      resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("xml", new GenericXMLResourceFactoryImpl());

      Resource resource = resourceSet.getResource(URI.createPlatformResourceURI(file.getFullPath().toString(), true), true);
      resource.setURI(URI.createPlatformResourceURI(file.getFullPath().toString() + ".save.xml", true));
      try
      {
        resource.save(Collections.EMPTY_MAP);
      }
      catch (IOException exception)
      {
        XSDEditorPlugin.INSTANCE.log(exception);
        exception.printStackTrace();
      }

      List<EPackage> ePackages = new ArrayList<EPackage>();
      for (Resource otherResource : resourceSet.getResources())
      {
        for (Object object : otherResource.getContents())
        {
          if (object instanceof EPackage)
          {
            ePackages.add((EPackage)object);
          }
        }
      }

      Resource ePackagesResource = resourceSet.createResource(URI.createPlatformResourceURI(file.getFullPath().toString() + ".ecore", true));
      ePackagesResource.getContents().addAll(EcoreUtil.copyAll(ePackages));
      try
      {
        ePackagesResource.save(Collections.EMPTY_MAP);
      }
      catch (IOException exception)
      {
        XSDEditorPlugin.INSTANCE.log(exception);
        exception.printStackTrace();
      }

      try
      {
        XSDParser xsdParser = new XSDParser(null);
        xsdParser.parse(URI.createPlatformResourceURI(file.getFullPath().toString(), true).toString());
        Document document = xsdParser.getDocument();
        OutputStream outputStream = 
          resourceSet.getURIConverter().createOutputStream
            (URI.createPlatformResourceURI(file.getFullPath().toString() + ".format.xml", true));
        XSDResourceImpl.serialize(outputStream, document);
        outputStream.close();
      }
      catch (IOException exception)
      {
        XSDEditorPlugin.INSTANCE.log(exception);
        exception.printStackTrace();
      }

      try
      {
        XSDParser xsdParser = new XSDParser(null);
        xsdParser.parse(URI.createPlatformResourceURI(file.getFullPath().toString() + ".save.xml", true).toString());
        Document document = xsdParser.getDocument();
        OutputStream outputStream = 
          resourceSet.getURIConverter().createOutputStream
            (URI.createPlatformResourceURI(file.getFullPath().toString() + ".save.format.xml", true));
        XSDResourceImpl.serialize(outputStream, document);
        outputStream.close();
      }
      catch (IOException exception)
      {
        XSDEditorPlugin.INSTANCE.log(exception);
        exception.printStackTrace();
      }
    }

    @Override
    public void selectionChanged(IAction action, ISelection selection)
    {
      if (selection instanceof IStructuredSelection)
      {
        Object object = ((IStructuredSelection)selection).getFirstElement();
        if (object instanceof IFile)
        {
          file = (IFile)object;
          action.setEnabled(true);
          return;
        }
        else if (object instanceof IContainer)
        {
          container = (IContainer)object;
          action.setEnabled(true);
          return;
        }
      }
      file = null;
      container = null;
      action.setEnabled(false);
    }
  }
}
