[236609] Support an option to not sort attributes and record map
creation and sort choice as an annotation.
diff --git a/features/org.eclipse.xsd.ecore.converter-feature/feature.xml b/features/org.eclipse.xsd.ecore.converter-feature/feature.xml
index 8c23b64..3d92582 100644
--- a/features/org.eclipse.xsd.ecore.converter-feature/feature.xml
+++ b/features/org.eclipse.xsd.ecore.converter-feature/feature.xml
@@ -2,7 +2,7 @@
 <feature
       id="org.eclipse.xsd.ecore.converter"
       label="%featureName"
-      version="2.7.0.qualifier"
+      version="2.8.0.qualifier"
       provider-name="%providerName"
       license-feature="org.eclipse.xsd.license"
       license-feature-version="2.7.0.qualifier">
diff --git a/plugins/org.eclipse.xsd.ecore.importer/META-INF/MANIFEST.MF b/plugins/org.eclipse.xsd.ecore.importer/META-INF/MANIFEST.MF
index d207165..516f8b7 100644
--- a/plugins/org.eclipse.xsd.ecore.importer/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.xsd.ecore.importer/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.xsd.ecore.importer; singleton:=true
-Bundle-Version: 2.6.0.qualifier
+Bundle-Version: 2.7.0.qualifier
 Bundle-ClassPath: .
 Bundle-Activator: org.eclipse.xsd.ecore.importer.XSDImporterPlugin$Implementation
 Bundle-Vendor: %providerName
diff --git a/plugins/org.eclipse.xsd.ecore.importer/plugin.properties b/plugins/org.eclipse.xsd.ecore.importer/plugin.properties
index 30ef374..c04e367 100644
--- a/plugins/org.eclipse.xsd.ecore.importer/plugin.properties
+++ b/plugins/org.eclipse.xsd.ecore.importer/plugin.properties
@@ -22,6 +22,7 @@
 _UI_XSDImportNewProject_description = Specify one or more '.xsd' or '.wsdl' URIs, try to load them, and choose a file name for the generator model
 
 _UI_Create_XML_Schema_to_Ecore_Map = Create XML Schema to Ecore &Map
+_UI_Sort_Attributes = &Sort Attributes Alphabetically
 
 _UI_ErrorsWereDetectedXMLSchema_message =  Problems were detected while validating and converting the XML Schemas
 _UI_SpecifyAValidXMLSchema_message = Specify a valid XML Schema and try loading again
diff --git a/plugins/org.eclipse.xsd.ecore.importer/src/org/eclipse/xsd/ecore/importer/XSDImporter.java b/plugins/org.eclipse.xsd.ecore.importer/src/org/eclipse/xsd/ecore/importer/XSDImporter.java
index fb9fcf2..7ede1da 100644
--- a/plugins/org.eclipse.xsd.ecore.importer/src/org/eclipse/xsd/ecore/importer/XSDImporter.java
+++ b/plugins/org.eclipse.xsd.ecore.importer/src/org/eclipse/xsd/ecore/importer/XSDImporter.java
@@ -1,11 +1,11 @@
 /**
- * Copyright (c) 2005-2006 IBM Corporation and others.
+ * Copyright (c) 2005-2012 IBM Corporation and others
  * All rights reserved.   This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
- * 
- * Contributors: 
+ *
+ * Contributors:
  *   IBM - Initial API and implementation
  */
 package org.eclipse.xsd.ecore.importer;
@@ -16,11 +16,14 @@
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.Platform;
 
+import org.eclipse.emf.codegen.ecore.genmodel.GenAnnotation;
+import org.eclipse.emf.codegen.ecore.genmodel.GenModel;
 import org.eclipse.emf.codegen.ecore.genmodel.GenPackage;
 import org.eclipse.emf.codegen.ecore.genmodel.GenResourceKind;
 import org.eclipse.emf.common.util.BasicDiagnostic;
 import org.eclipse.emf.common.util.Diagnostic;
 import org.eclipse.emf.common.util.DiagnosticException;
+import org.eclipse.emf.common.util.EList;
 import org.eclipse.emf.common.util.Monitor;
 import org.eclipse.emf.common.util.URI;
 import org.eclipse.emf.converter.ConverterPlugin;
@@ -35,6 +38,16 @@
 
 public class XSDImporter extends ModelImporter
 {
+  /**
+   * @since 2.9
+   */
+  protected static final String SORT_ATTRIBUTES_KEY = "sortAttributes";
+
+  /**
+   * @since 2.9
+   */
+  protected static final String CREATE_MAP_KEY = "createMap";
+
   public static class MapHelper
   {
     public void setNewMapper(XSDEcoreBuilder ecoreBuilder)
@@ -51,9 +64,15 @@
     }
   }
 
-  protected boolean createEcoreMap = false;
+  protected boolean createEcoreMap;
+
   protected EObject mappingRoot;
 
+  /**
+   * @since 2.9
+   */
+  protected boolean sortAttributes = true;
+
   @Override
   public void dispose()
   {
@@ -82,6 +101,22 @@
     return createEcoreMap && canCreateEcoreMap();
   }
 
+  /**
+   * @since 2.9
+   */
+  public void setSortAttributes(boolean sortAttributes)
+  {
+    this.sortAttributes = sortAttributes;
+  }
+
+  /**
+   * @since 2.9
+   */
+  public boolean sortAttributes()
+  {
+    return sortAttributes;
+  }
+
   public void setMappingRoot(EObject mappingRoot)
   {
     this.mappingRoot = mappingRoot;
@@ -112,12 +147,25 @@
       monitor.beginTask("", 2);
       monitor.subTask(XSDImporterPlugin.INSTANCE.getString("_UI_Loading_message", new Object []{ locationURIs }));
 
-      XSDEcoreBuilder ecoreBuilder = new XSDEcoreBuilder();
+      setMappingRoot(null);
+
+      XSDEcoreBuilder ecoreBuilder =
+        sortAttributes() ?
+          new XSDEcoreBuilder() :
+          new XSDEcoreBuilder()
+          {
+            @Override
+            protected boolean useSortedAttributes()
+            {
+              return false;
+            }
+          };
+
       if (createEcoreMap())
       {
         new MapHelper().setNewMapper(ecoreBuilder);
       }
-      
+
       @SuppressWarnings("unchecked")
       List<Object> result = (List<Object>)(List<?>)(Collection<?>)ecoreBuilder.generate(locationURIs);
 
@@ -196,9 +244,11 @@
     IPath genModelFileFullPath = getGenModelPath();
     URI genModelURI = createFileURI(genModelFileFullPath.toString());
 
+    GenModel genModel = getGenModel();
+    EList<String> foreignModel = genModel.getForeignModel();
     for (URI uri : getModelLocationURIs())
     {
-      getGenModel().getForeignModel().add(makeRelative(uri, genModelURI).toString());
+      foreignModel.add(makeRelative(uri, genModelURI).toString());
     }
 
     if (getMappingRoot() != null)
@@ -211,6 +261,50 @@
   }
 
   @Override
+  public void prepareGenModelAndEPackages(Monitor monitor)
+  {
+    super.prepareGenModelAndEPackages(monitor);
+
+    GenModel genModel = getGenModel();
+
+    GenAnnotation annotation = genModel.getGenAnnotation(getConverterGenAnnotationSource());
+    if (!sortAttributes())
+    {
+      if (annotation == null)
+      {
+        annotation = genModel.createGenAnnotation();
+        annotation.setSource(getConverterGenAnnotationSource());
+      }
+      annotation.getDetails().put(SORT_ATTRIBUTES_KEY, "false");
+      genModel.getGenAnnotations().add(annotation);
+    }
+    else if (annotation != null)
+    {
+      annotation.getDetails().remove(SORT_ATTRIBUTES_KEY);
+    }
+
+    if (getMappingRoot() != null)
+    {
+      if (annotation == null)
+      {
+        annotation = genModel.createGenAnnotation();
+        annotation.setSource(getConverterGenAnnotationSource());
+        genModel.getGenAnnotations().add(annotation);
+      }
+      annotation.getDetails().put(CREATE_MAP_KEY, "true");
+    }
+    else if (annotation != null)
+    {
+      annotation.getDetails().remove(CREATE_MAP_KEY);
+    }
+
+    if (annotation != null && annotation.getDetails().isEmpty())
+    {
+      genModel.getGenAnnotations().remove(annotation);
+    }
+  }
+
+  @Override
   protected List<Resource> computeResourcesToBeSaved()
   {
     List<Resource> resources = super.computeResourcesToBeSaved();
@@ -224,9 +318,10 @@
   @Override
   protected void handleOriginalGenModel() throws DiagnosticException
   {
-    URI genModelURI = getOriginalGenModel().eResource().getURI();
+    GenModel originalGenModel = getOriginalGenModel();
+    URI genModelURI = originalGenModel.eResource().getURI();
     StringBuffer text = new StringBuffer();
-    for (String value : getOriginalGenModel().getForeignModel())
+    for (String value : originalGenModel.getForeignModel())
     {
       if (value.endsWith(".xsd") || value.endsWith(".wsdl"))
       {
@@ -234,6 +329,12 @@
         text.append(" ");
       }
     }
+    GenAnnotation annotation = originalGenModel.getGenAnnotation(getConverterGenAnnotationSource());
+    if (annotation != null)
+    {
+      setSortAttributes(!"false".equals(annotation.getDetails().get(SORT_ATTRIBUTES_KEY)));
+      setCreateEcoreMap("true".equals(annotation.getDetails().get(CREATE_MAP_KEY)));
+    }
     setModelLocation(text.toString().trim());
   }
 }
\ No newline at end of file
diff --git a/plugins/org.eclipse.xsd.ecore.importer/src/org/eclipse/xsd/ecore/importer/ui/XSDDetailPage.java b/plugins/org.eclipse.xsd.ecore.importer/src/org/eclipse/xsd/ecore/importer/ui/XSDDetailPage.java
index bbd7eb5..698c59c 100644
--- a/plugins/org.eclipse.xsd.ecore.importer/src/org/eclipse/xsd/ecore/importer/ui/XSDDetailPage.java
+++ b/plugins/org.eclipse.xsd.ecore.importer/src/org/eclipse/xsd/ecore/importer/ui/XSDDetailPage.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2005-2006 IBM Corporation and others.
+ * Copyright (c) 2005-2012 IBM Corporation and others.
  * All rights reserved.   This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -30,6 +30,11 @@
 {
   protected Button createMapButton;
 
+  /**
+   * @since 2.9
+   */
+  protected Button sortAttributesButton;
+
   public XSDDetailPage(ModelImporter modelImporter, String pageName)
   {
     super(modelImporter, pageName);
@@ -47,6 +52,11 @@
       createMapButton.removeListener(SWT.Selection, this);
       createMapButton = null;
     }
+    if (sortAttributesButton != null)
+    {
+      sortAttributesButton.removeListener(SWT.Selection, this);
+      sortAttributesButton = null;
+    }
 
     super.dispose();
   }
@@ -59,9 +69,14 @@
   @Override
   protected void addDetailControl(Composite parent)
   {
-    if (getXSDImporter().canCreateEcoreMap())
+    XSDImporter xsdImporter = getXSDImporter();
+    if (xsdImporter.canCreateEcoreMap())
     {
       createMapButton = new Button(parent, SWT.CHECK);
+      if (xsdImporter.createEcoreMap())
+      {
+        createMapButton.setSelection(true);
+      }
       createMapButton.setText(XSDImporterPlugin.INSTANCE.getString("_UI_Create_XML_Schema_to_Ecore_Map"));
       {
         GridData data = new GridData();
@@ -70,14 +85,34 @@
       }
       createMapButton.addListener(SWT.Selection, this);
     }
+
+    sortAttributesButton = new Button(parent, SWT.CHECK);
+    if (xsdImporter.sortAttributes())
+    {
+      sortAttributesButton.setSelection(true);
+    }
+    sortAttributesButton.setText(XSDImporterPlugin.INSTANCE.getString("_UI_Sort_Attributes"));
+    {
+      GridData data = new GridData();
+      data.horizontalSpan = 1;
+      sortAttributesButton.setLayoutData(data);
+    }
+    sortAttributesButton.addListener(SWT.Selection, this);
   }
 
   @Override
   protected void doHandleEvent(Event event)
   {
-    if (event.type == SWT.Selection && event.widget == createMapButton)
+    if (event.type == SWT.Selection && (event.widget == createMapButton || event.widget == sortAttributesButton))
     {
-      getXSDImporter().setCreateEcoreMap(createMapButton.getSelection());
+      if (event.widget == createMapButton)
+      {
+        getXSDImporter().setCreateEcoreMap(createMapButton.getSelection());
+      }
+      else
+      {
+        getXSDImporter().setSortAttributes(sortAttributesButton.getSelection());
+      }
       if (uriText.getText().trim().length() > 0)
       {
         refreshModel();