[170557] Extensions and Extension Properties View Fixes.
diff --git a/bundles/org.eclipse.wst.xsd.ui/src-common/org/eclipse/wst/xsd/ui/internal/common/commands/ExtensibleAddExtensionCommand.java b/bundles/org.eclipse.wst.xsd.ui/src-common/org/eclipse/wst/xsd/ui/internal/common/commands/ExtensibleAddExtensionCommand.java
index b407f1f..9e37158 100644
--- a/bundles/org.eclipse.wst.xsd.ui/src-common/org/eclipse/wst/xsd/ui/internal/common/commands/ExtensibleAddExtensionCommand.java
+++ b/bundles/org.eclipse.wst.xsd.ui/src-common/org/eclipse/wst/xsd/ui/internal/common/commands/ExtensibleAddExtensionCommand.java
@@ -10,11 +10,16 @@
  *******************************************************************************/
 package org.eclipse.wst.xsd.ui.internal.common.commands;
 
+import java.util.List;
+
 import org.eclipse.wst.xml.core.internal.contentmodel.util.NamespaceTable;
+import org.eclipse.wst.xsd.ui.internal.common.util.XSDCommonUIUtils;
+import org.eclipse.xsd.XSDAnnotation;
 import org.eclipse.xsd.XSDConcreteComponent;
 import org.eclipse.xsd.XSDElementDeclaration;
 import org.eclipse.xsd.XSDSchema;
 import org.eclipse.xsd.util.XSDConstants;
+import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
 public class ExtensibleAddExtensionCommand extends AddExtensionCommand
@@ -53,6 +58,16 @@
     this.component = input;
     this.element = element;
   }
+  
+  public XSDAnnotation getXSDAnnotation()
+  {
+    if (component != null)
+    {
+      XSDAnnotation xsdAnnotation = XSDCommonUIUtils.getInputXSDAnnotation(component, false);
+      return xsdAnnotation;
+    }
+    return null;
+  }
 
   public void execute()
   {
@@ -60,8 +75,9 @@
     {
       beginRecording(component.getElement());
       super.execute();
-      
-      addCustomizedActions();
+      doPreprocessing();
+      addExtensionNode();
+      doCustomizedActions();
       
       formatChild(component.getElement());
     }
@@ -71,7 +87,50 @@
     }
   }
   
-  public void addCustomizedActions()
+  protected void doPreprocessing()
+  {
+    
+  }
+  
+  protected void addExtensionNode()
+  {
+    XSDAnnotation xsdAnnotation = XSDCommonUIUtils.getInputXSDAnnotation(component, true);
+    XSDSchema schema= xsdAnnotation.getSchema();
+    Element schemaElement = schema.getElement();
+
+    if (xsdAnnotation.getApplicationInformation().size() == 0)
+    {
+      appInfo = xsdAnnotation.createApplicationInformation(null);
+      xsdAnnotation.getElement().appendChild(appInfo);
+      List appInfos = xsdAnnotation.getApplicationInformation();
+      appInfos.add(appInfo);
+    }
+    else
+    {
+      // use the first appInfo
+      appInfo = (Element)xsdAnnotation.getApplicationInformation().get(0);
+    }
+
+    if (appInfo != null)
+    {
+      Document doc = appInfo.getOwnerDocument();
+      String prefix = addToNamespaceTable(schemaElement);
+      newElement = doc.createElementNS(extensionsSchemaSpec.getNamespaceURI(), element.getName());
+      newElement.setPrefix(prefix);   
+      appInfo.appendChild(newElement);
+
+      xsdAnnotation.updateElement();
+    }
+  }
+  
+  protected String addToNamespaceTable(Element schemaElement)
+  {
+    String prefix = addNamespaceDeclarationIfRequired(schemaElement, "p", extensionsSchemaSpec.getNamespaceURI());
+    return prefix;
+  }
+
+  
+  protected void doCustomizedActions()
   {
    
   }
@@ -79,11 +138,6 @@
   public void undo()
   {
     super.undo();
-//    XSDAnnotation xsdAnnotation = XSDCommonUIUtils.getInputXSDAnnotation(component, false);
-//    xsdAnnotation.getElement().removeChild(appInfo);
-//    List appInfos = xsdAnnotation.getApplicationInformation();
-//    appInfos.remove(appInfo);
-//    xsdAnnotation.updateElement();
   }
 
   public Object getNewObject()
@@ -126,11 +180,13 @@
     {
       if (prefix != null)
       {
-        schemaElement.setAttribute(prefix + ":" + attributeName, attributeValue);  
+        if (schemaElement.getAttributeNode(prefix + ":" + attributeName) == null)
+          schemaElement.setAttribute(prefix + ":" + attributeName, attributeValue);  
       }
       else
       {
-        schemaElement.setAttribute(attributeName, attributeValue);
+        if (schemaElement.getAttributeNode(attributeName) == null)
+          schemaElement.setAttribute(attributeName, attributeValue);
       }
     }
     catch (Exception e)
diff --git a/bundles/org.eclipse.wst.xsd.ui/src-common/org/eclipse/wst/xsd/ui/internal/common/commands/ExtensibleRemoveExtensionNodeCommand.java b/bundles/org.eclipse.wst.xsd.ui/src-common/org/eclipse/wst/xsd/ui/internal/common/commands/ExtensibleRemoveExtensionNodeCommand.java
new file mode 100644
index 0000000..cb5ff38
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsd.ui/src-common/org/eclipse/wst/xsd/ui/internal/common/commands/ExtensibleRemoveExtensionNodeCommand.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Copyright (c) 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 v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xsd.ui.internal.common.commands;
+
+import org.eclipse.wst.xsd.ui.internal.util.XSDDOMHelper;
+import org.eclipse.xsd.XSDConcreteComponent;
+import org.eclipse.xsd.util.XSDConstants;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Node;
+
+public class ExtensibleRemoveExtensionNodeCommand extends BaseCommand
+{
+  protected Node node;
+  protected XSDConcreteComponent input;
+  
+  public ExtensibleRemoveExtensionNodeCommand(String label)
+  {
+    super(label);
+  }
+  
+  public void setNode(Node node)
+  {
+    this.node = node;
+  }
+
+  public XSDConcreteComponent getInput()
+  {
+    return input;
+  }
+
+  public void setInput(XSDConcreteComponent input)
+  {
+    this.input = input;
+  }
+
+  public void execute()
+  {
+    super.execute();
+    try
+    {
+      beginRecording(node);
+      
+      doPreprocessing();
+      
+      if (node.getNodeType() == Node.ATTRIBUTE_NODE)
+      {
+        Attr attr = (Attr) node;
+        attr.getOwnerElement().removeAttributeNode(attr);
+      }
+      else if (node.getNodeType() == Node.ELEMENT_NODE)
+      {
+        Node parent = node.getParentNode();
+        if (parent != null)
+        {
+          XSDDOMHelper.removeNodeAndWhitespace(node);
+          
+          if (XSDDOMHelper.hasOnlyWhitespace(parent))
+          {
+            if (XSDConstants.APPINFO_ELEMENT_TAG.equals(parent.getLocalName()))
+            {
+              XSDDOMHelper.removeNodeAndWhitespace(parent);
+            }
+          }
+        }
+      }
+      
+      doCustomizedActions();
+
+    }
+    finally
+    {
+      endRecording();
+    }
+  }
+
+  protected void doPreprocessing()
+  {
+   
+  }
+
+  protected void doCustomizedActions()
+  {
+   
+  }
+
+}
diff --git a/bundles/org.eclipse.wst.xsd.ui/src-common/org/eclipse/wst/xsd/ui/internal/common/properties/sections/ExtensionsSection.java b/bundles/org.eclipse.wst.xsd.ui/src-common/org/eclipse/wst/xsd/ui/internal/common/properties/sections/ExtensionsSection.java
index 7bff8a8..c894644 100644
--- a/bundles/org.eclipse.wst.xsd.ui/src-common/org/eclipse/wst/xsd/ui/internal/common/properties/sections/ExtensionsSection.java
+++ b/bundles/org.eclipse.wst.xsd.ui/src-common/org/eclipse/wst/xsd/ui/internal/common/properties/sections/ExtensionsSection.java
@@ -10,18 +10,28 @@
  *******************************************************************************/
 package org.eclipse.wst.xsd.ui.internal.common.properties.sections;
 
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
 import org.eclipse.gef.commands.Command;
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
 import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.Viewer;
 import org.eclipse.ui.IWorkbenchPart;
 import org.eclipse.wst.xsd.ui.internal.common.commands.AddExtensionAttributeCommand;
 import org.eclipse.wst.xsd.ui.internal.common.commands.AddExtensionCommand;
 import org.eclipse.wst.xsd.ui.internal.common.commands.AddExtensionElementCommand;
 import org.eclipse.wst.xsd.ui.internal.common.commands.ExtensibleAddExtensionCommand;
+import org.eclipse.wst.xsd.ui.internal.common.commands.ExtensibleRemoveExtensionNodeCommand;
 import org.eclipse.wst.xsd.ui.internal.common.commands.RemoveExtensionNodeCommand;
+import org.eclipse.wst.xsd.ui.internal.common.properties.sections.appinfo.AddExtensionsComponentDialog;
+import org.eclipse.wst.xsd.ui.internal.common.properties.sections.appinfo.CategoryProvider;
 import org.eclipse.wst.xsd.ui.internal.common.properties.sections.appinfo.DOMExtensionTreeLabelProvider;
 import org.eclipse.wst.xsd.ui.internal.common.properties.sections.appinfo.ExtensionsSchemasRegistry;
+import org.eclipse.wst.xsd.ui.internal.common.properties.sections.appinfo.SpecificationForExtensionsSchema;
 import org.eclipse.wst.xsd.ui.internal.common.properties.sections.appinfo.XSDExtensionTreeContentProvider;
 import org.eclipse.wst.xsd.ui.internal.common.util.Messages;
 import org.eclipse.wst.xsd.ui.internal.editor.XSDEditorPlugin;
@@ -44,6 +54,17 @@
     setExtensionTreeContentProvider(new XSDExtensionTreeContentProvider());
   }
   
+  protected AddExtensionsComponentDialog createAddExtensionsComponentDialog()
+  {
+    return new AddExtensionsComponentDialog(composite.getShell(), getExtensionsSchemasRegistry())
+    {
+      protected IStructuredContentProvider getCategoryContentProvider()
+      {
+        return new XSDCategoryContentProvider();
+      }
+    };
+  }
+  
   public void setInput(IWorkbenchPart part, ISelection selection)
   {
     super.setInput(part, selection); 
@@ -88,7 +109,7 @@
     if (o instanceof XSDElementDeclaration)
     {
       XSDElementDeclaration element = (XSDElementDeclaration) o;
-      ExtensibleAddExtensionCommand extensibleAddExtensionCommand = getExtensionsSchemasRegistry().getAddExtensionHandler(element.getTargetNamespace());
+      ExtensibleAddExtensionCommand extensibleAddExtensionCommand = getExtensionsSchemasRegistry().getAddExtensionCommand(element.getTargetNamespace());
       if (extensibleAddExtensionCommand != null)
       {
         extensibleAddExtensionCommand.setInputs((XSDConcreteComponent) input, element);
@@ -111,16 +132,26 @@
   {
     Command command = null;
     try
-    {     
+    {
       if (o instanceof Node)
-      {            
-        command = new RemoveExtensionNodeCommand(Messages._UI_ACTION_DELETE_APPINFO_ELEMENT, (Node)o);  
-        command.execute();
+      {
+        Node node = (Node)o;
+        ExtensibleRemoveExtensionNodeCommand removeCommand = getExtensionsSchemasRegistry().getRemoveExtensionNodeCommand(node.getNamespaceURI());
+        if (removeCommand != null)
+        {
+          removeCommand.setInput((XSDConcreteComponent)input);
+          removeCommand.setNode(node);
+          return removeCommand;
+        }
+        else
+        {
+          command = new RemoveExtensionNodeCommand(Messages._UI_ACTION_DELETE_APPINFO_ELEMENT, node);  
+          // command.execute();
+        }
       }
     }
     catch (Exception e)
     {
-      e.printStackTrace();
     }
     return command;
   }  
@@ -147,4 +178,65 @@
   {
     return XSDEditorPlugin.getPlugin().getPreferenceStore();
   }
+  
+  static class XSDCategoryContentProvider implements IStructuredContentProvider
+  {
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
+     */
+    public Object[] getElements(Object inputElement)
+    {    
+      SpecificationForExtensionsSchema[] extensionsSchemaSpecs = null;
+      try
+      {
+        List inputList = (List) inputElement;
+        
+        List total = new ArrayList();
+        total.addAll(inputList);
+        
+        List dynamicCategories = XSDEditorPlugin.getPlugin().getExtensionsSchemasRegistry().getCategoryProviders();
+        for (Iterator iter = dynamicCategories.iterator(); iter.hasNext(); )
+        {
+          CategoryProvider categoryProvider = (CategoryProvider)iter.next();
+          for (Iterator it = categoryProvider.getCategories().iterator(); it.hasNext(); )
+          {
+            SpecificationForExtensionsSchema sp = (SpecificationForExtensionsSchema)it.next();
+            total.add(sp);
+          }
+        }
+
+        extensionsSchemaSpecs = (SpecificationForExtensionsSchema[]) total.toArray(new SpecificationForExtensionsSchema[0]);
+      }
+      catch (Exception e)
+      {
+      }
+      return extensionsSchemaSpecs;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+     */
+    public void dispose()
+    {
+      // Do nothing
+
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer,
+     *      java.lang.Object, java.lang.Object)
+     */
+    public void inputChanged(Viewer viewer, Object oldInput, Object newInput)
+    {
+      // Do nothing
+
+    }
+  }
+
 }
\ No newline at end of file
diff --git a/bundles/org.eclipse.wst.xsd.ui/src-common/org/eclipse/wst/xsd/ui/internal/common/properties/sections/appinfo/AddExtensionsComponentDialog.java b/bundles/org.eclipse.wst.xsd.ui/src-common/org/eclipse/wst/xsd/ui/internal/common/properties/sections/appinfo/AddExtensionsComponentDialog.java
index 05075e0..8d4aef3 100644
--- a/bundles/org.eclipse.wst.xsd.ui/src-common/org/eclipse/wst/xsd/ui/internal/common/properties/sections/appinfo/AddExtensionsComponentDialog.java
+++ b/bundles/org.eclipse.wst.xsd.ui/src-common/org/eclipse/wst/xsd/ui/internal/common/properties/sections/appinfo/AddExtensionsComponentDialog.java
@@ -100,6 +100,11 @@
   public void setInitialCategorySelection(SpecificationForExtensionsSchema spec){
 	  currentExtCategory = spec;
   }
+  
+  protected IStructuredContentProvider getCategoryContentProvider()
+  {
+    return new CategoryContentProvider();
+  }
 
   protected Control createDialogArea(Composite container)
   {
@@ -120,7 +125,7 @@
     new Label(categoryComposite, SWT.NONE);
 
     categoryTableViewer = new TableViewer(categoryComposite, getTableStyle());
-    categoryTableViewer.setContentProvider(new CategoryContentProvider());
+    categoryTableViewer.setContentProvider(getCategoryContentProvider());
     categoryTableViewer.setLabelProvider(new CategoryLabelProvider());
     categoryTableViewer.setInput(fInput);
     categoryTableViewer.addSelectionChangedListener(this);
@@ -625,7 +630,6 @@
       }
       catch (Exception e)
       {
-        e.printStackTrace();
       }
       return extensionsSchemaSpecs;
     }
diff --git a/bundles/org.eclipse.wst.xsd.ui/src-common/org/eclipse/wst/xsd/ui/internal/common/properties/sections/appinfo/CategoryProvider.java b/bundles/org.eclipse.wst.xsd.ui/src-common/org/eclipse/wst/xsd/ui/internal/common/properties/sections/appinfo/CategoryProvider.java
new file mode 100644
index 0000000..a3eb64a
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsd.ui/src-common/org/eclipse/wst/xsd/ui/internal/common/properties/sections/appinfo/CategoryProvider.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 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 v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xsd.ui.internal.common.properties.sections.appinfo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.wst.xml.core.internal.XMLCorePlugin;
+import org.eclipse.wst.xml.core.internal.catalog.provisional.ICatalog;
+import org.eclipse.wst.xml.core.internal.catalog.provisional.ICatalogEntry;
+import org.eclipse.wst.xml.core.internal.catalog.provisional.INextCatalog;
+
+public class CategoryProvider
+{
+  private ICatalog systemCatalog;
+
+  public CategoryProvider()
+  {
+    
+  }
+  
+  /**
+   * Extenders should implement and return a list of 
+   * SpecificationForExtensionsSchema
+   * @return
+   */
+  public List getCategories()
+  {
+    return new ArrayList();
+  }
+  
+  /**
+   * Helper method to find the physical location of the schema
+   * in the XML Catalog
+   * @param namespaceURI
+   * @return physical location of the schema
+   */
+  public String locateFileUsingCatalog(String namespaceURI)
+  {
+    retrieveCatalog();
+
+    ICatalogEntry[] entries = systemCatalog.getCatalogEntries();
+    for (int i = 0; i < entries.length; i++)
+    {
+      if (entries[i].getKey().equals(namespaceURI))
+        return entries[i].getURI();
+    }
+
+    return null;
+  }
+
+  private void retrieveCatalog()
+  {
+    if (systemCatalog != null)
+      return;
+
+    ICatalog defaultCatalog = XMLCorePlugin.getDefault().getDefaultXMLCatalog();
+    INextCatalog[] nextCatalogs = defaultCatalog.getNextCatalogs();
+    for (int i = 0; i < nextCatalogs.length; i++)
+    {
+      INextCatalog catalog = nextCatalogs[i];
+      ICatalog referencedCatalog = catalog.getReferencedCatalog();
+      if (referencedCatalog != null)
+      {
+        if (XMLCorePlugin.SYSTEM_CATALOG_ID.equals(referencedCatalog.getId()))
+        {
+          systemCatalog = referencedCatalog;
+        }
+      }
+    }
+  }
+
+}
diff --git a/bundles/org.eclipse.wst.xsd.ui/src-common/org/eclipse/wst/xsd/ui/internal/common/properties/sections/appinfo/ExtensionsSchemasRegistry.java b/bundles/org.eclipse.wst.xsd.ui/src-common/org/eclipse/wst/xsd/ui/internal/common/properties/sections/appinfo/ExtensionsSchemasRegistry.java
index 46044bc..6c98ddd 100644
--- a/bundles/org.eclipse.wst.xsd.ui/src-common/org/eclipse/wst/xsd/ui/internal/common/properties/sections/appinfo/ExtensionsSchemasRegistry.java
+++ b/bundles/org.eclipse.wst.xsd.ui/src-common/org/eclipse/wst/xsd/ui/internal/common/properties/sections/appinfo/ExtensionsSchemasRegistry.java
@@ -11,7 +11,7 @@
 package org.eclipse.wst.xsd.ui.internal.common.properties.sections.appinfo;
 
 import java.util.ArrayList;
-import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
 import java.util.StringTokenizer;
 
@@ -24,6 +24,7 @@
 import org.eclipse.wst.xml.core.internal.catalog.provisional.ICatalogEntry;
 import org.eclipse.wst.xml.core.internal.catalog.provisional.INextCatalog;
 import org.eclipse.wst.xsd.ui.internal.common.commands.ExtensibleAddExtensionCommand;
+import org.eclipse.wst.xsd.ui.internal.common.commands.ExtensibleRemoveExtensionNodeCommand;
 import org.w3c.dom.Element;
 
 public class ExtensionsSchemasRegistry
@@ -36,12 +37,13 @@
   public static final String XSDFILEURL = "xsdFileURL"; //$NON-NLS-1$
   public static final String LABELPROVIDER = "labelProviderClass"; //$NON-NLS-1$
   public static final String ADD_COMMAND_CLASS = "addCommandClass"; //$NON-NLS-1$
+  public static final String DELETE_COMMAND_CLASS = "deleteCommandClass"; //$NON-NLS-1$
+  public static final String CATEGORY_PROVIDER_CLASS = "class"; //$NON-NLS-1$
   
   protected IPreferenceStore prefStore;
   protected String extensionId;
 
-  HashMap propertyMap, commandMap;
-  ArrayList nsURIProperties;
+  protected ArrayList nsURIProperties, categoryProviderList;
   private ICatalog systemCatalog;
   private String deprecatedExtensionId;
   
@@ -69,8 +71,7 @@
     }
  
     nsURIProperties = new ArrayList();
-    propertyMap = new HashMap();
-    commandMap = new HashMap();
+    categoryProviderList = new ArrayList();
 
     getAllExtensionsSchemasContribution(extensionId);
     if (deprecatedExtensionId != null)
@@ -104,75 +105,116 @@
       for (int i = 0; i < asiPropertiesList.length; i++)
       {
         IConfigurationElement asiPropertiesElement = asiPropertiesList[i];
-        String description = asiPropertiesElement.getAttribute(DESCRIPTION);
-        String displayName = asiPropertiesElement.getAttribute(DISPLAYNAME);
-        String namespaceURI = asiPropertiesElement.getAttribute(NAMESPACEURI);
-        String xsdFileURL = asiPropertiesElement.getAttribute(XSDFILEURL);
-        String labelProviderClass = asiPropertiesElement.getAttribute(LABELPROVIDER);
-        String actionHandlerClass = asiPropertiesElement.getAttribute(ADD_COMMAND_CLASS);
+        String elementName = asiPropertiesElement.getName();
 
-        if (displayName == null)
+        if ("category".equals(elementName))
         {
-          // If there is no display name, force the user
-          // to manually create a name. Therefore, we ignore entry without
-          // a display name.
-          continue;
-        }
-
-        if (xsdFileURL == null)
-        {
-          xsdFileURL = locateFileUsingCatalog(namespaceURI);
-        }
-
-        SpecificationForExtensionsSchema extensionsSchemaSpec = createEntry();
-        extensionsSchemaSpec.setDescription(description);
-        extensionsSchemaSpec.setDisplayName(displayName);
-        extensionsSchemaSpec.setNamespaceURI(namespaceURI);
-        extensionsSchemaSpec.setDefautSchema();
-
-        String pluginId = asiPropertiesElement.getDeclaringExtension().getContributor().getName();
-
-        if (labelProviderClass != null)
-        {
-          ILabelProvider labelProvider = null;
-          try
+          String description = asiPropertiesElement.getAttribute(DESCRIPTION);
+          String displayName = asiPropertiesElement.getAttribute(DISPLAYNAME);
+          String namespaceURI = asiPropertiesElement.getAttribute(NAMESPACEURI);
+          String xsdFileURL = asiPropertiesElement.getAttribute(XSDFILEURL);
+          String labelProviderClass = asiPropertiesElement.getAttribute(LABELPROVIDER);
+          String addCommandClass = asiPropertiesElement.getAttribute(ADD_COMMAND_CLASS);
+          String deleteCommandClass = asiPropertiesElement.getAttribute(DELETE_COMMAND_CLASS);
+          
+          if (displayName == null)
           {
-            Class theClass = Platform.getBundle(pluginId).loadClass(labelProviderClass);
-            if (theClass != null)
+            // If there is no display name, force the user
+            // to manually create a name. Therefore, we ignore entry without
+            // a display name.
+            continue;
+          }
+
+          if (xsdFileURL == null)
+          {
+            xsdFileURL = locateFileUsingCatalog(namespaceURI);
+          }
+
+          SpecificationForExtensionsSchema extensionsSchemaSpec = createEntry();
+          extensionsSchemaSpec.setDescription(description);
+          extensionsSchemaSpec.setDisplayName(displayName);
+          extensionsSchemaSpec.setNamespaceURI(namespaceURI);
+          extensionsSchemaSpec.setDefautSchema();
+
+          String pluginId = asiPropertiesElement.getDeclaringExtension().getContributor().getName();
+
+          if (labelProviderClass != null)
+          {
+            ILabelProvider labelProvider = null;
+            try
             {
-              labelProvider = (ILabelProvider) theClass.newInstance();
-              if (labelProvider != null)
+              Class theClass = Platform.getBundle(pluginId).loadClass(labelProviderClass);
+              if (theClass != null)
               {
-                propertyMap.put(namespaceURI, labelProvider);
-                extensionsSchemaSpec.setLabelProvider(labelProvider);
+                labelProvider = (ILabelProvider) theClass.newInstance();
+                if (labelProvider != null)
+                {
+                  extensionsSchemaSpec.setLabelProvider(labelProvider);
+                }
               }
             }
-          }
-          catch (Exception e)
-          {
-
-          }
-        }
-        
-        if (actionHandlerClass != null)
-        {
-          try
-          {
-            ExtensibleAddExtensionCommand actionHandler = (ExtensibleAddExtensionCommand)asiPropertiesElement.createExecutableExtension(ADD_COMMAND_CLASS);
-            if (actionHandler != null)
+            catch (Exception e)
             {
-              commandMap.put(namespaceURI, actionHandler);
-              extensionsSchemaSpec.setExtensibleAddExtensionCommand(actionHandler);
+
             }
           }
-          catch (Exception e)
+          
+          if (addCommandClass != null)
           {
+            try
+            {
+              ExtensibleAddExtensionCommand addCommand = (ExtensibleAddExtensionCommand)asiPropertiesElement.createExecutableExtension(ADD_COMMAND_CLASS);
+              if (addCommand != null)
+              {
+                extensionsSchemaSpec.setExtensibleAddExtensionCommand(addCommand);
+              }
+            }
+            catch (Exception e)
+            {
+            }
           }
+
+          if (deleteCommandClass != null)
+          {
+            try
+            {
+              ExtensibleRemoveExtensionNodeCommand deleteCommand = (ExtensibleRemoveExtensionNodeCommand)asiPropertiesElement.createExecutableExtension(DELETE_COMMAND_CLASS);
+              if (deleteCommand != null)
+              {
+                extensionsSchemaSpec.setExtensibleRemoveExtensionNodeCommand(deleteCommand);
+              }
+            }
+            catch (Exception e)
+            {
+            }
+          }
+
+          extensionsSchemaSpec.setLocation(LOCATION_PREFIX + pluginId + "/" + xsdFileURL); //$NON-NLS-1$
+
+          nsURIProperties.add(extensionsSchemaSpec);
+
+        }
+        else if ("categoryProvider".equals(elementName))
+        {
+          String categoryProviderClass = asiPropertiesElement.getAttribute(CATEGORY_PROVIDER_CLASS);
+          
+          if (categoryProviderClass != null)
+          {
+            try
+            {
+              CategoryProvider categoryProvider = (CategoryProvider)asiPropertiesElement.createExecutableExtension(CATEGORY_PROVIDER_CLASS);
+              if (categoryProvider != null)
+              {
+                categoryProviderList.add(categoryProvider);
+              }
+            }
+            catch (Exception e)
+            {
+            }
+          }
+          
         }
         
-        extensionsSchemaSpec.setLocation(LOCATION_PREFIX + pluginId + "/" + xsdFileURL); //$NON-NLS-1$
-
-        nsURIProperties.add(extensionsSchemaSpec);
       }
 
     }
@@ -180,42 +222,91 @@
     return nsURIProperties;
   }
   
-  public ExtensibleAddExtensionCommand getAddExtensionHandler(String namespace)
+  public ExtensibleAddExtensionCommand getAddExtensionCommand(String namespace)
   {
     // Didn't retrieve the config elements yet.
-    if (commandMap == null)
+    if (nsURIProperties == null)
     {
       getAllExtensionsSchemasContribution();
     }
-
-    Object object = commandMap.get(namespace);
-    if (object instanceof ExtensibleAddExtensionCommand)
+    
+    for (Iterator i = nsURIProperties.iterator(); i.hasNext(); )
     {
-      return (ExtensibleAddExtensionCommand) object;
+      SpecificationForExtensionsSchema spec = (SpecificationForExtensionsSchema)i.next();
+      String nsURI = spec.getNamespaceURI();
+      if (nsURI != null && nsURI.equals(namespace))
+      {
+        return spec.getExtensibleAddExtensionCommand();
+      }
     }
+
+    for (Iterator i = categoryProviderList.iterator(); i.hasNext(); )
+    {
+      CategoryProvider categoryProvider = (CategoryProvider)i.next();
+      for (Iterator j = categoryProvider.getCategories().iterator(); j.hasNext(); )
+      {
+        SpecificationForExtensionsSchema spec = (SpecificationForExtensionsSchema) j.next();
+        String namespaceURI = spec.getNamespaceURI();
+        if (namespaceURI != null && namespaceURI.equals(namespace))
+        {
+          return spec.getExtensibleAddExtensionCommand();
+        }
+      }
+    }
+
     return null;
   }
 
+  public ExtensibleRemoveExtensionNodeCommand getRemoveExtensionNodeCommand(String namespace)
+  {
+    // Didn't retrieve the config elements yet.
+    if (nsURIProperties == null)
+    {
+      getAllExtensionsSchemasContribution();
+    }
+    
+    for (Iterator i = nsURIProperties.iterator(); i.hasNext(); )
+    {
+      SpecificationForExtensionsSchema spec = (SpecificationForExtensionsSchema)i.next();
+      String nsURI = spec.getNamespaceURI();
+      if (nsURI != null && nsURI.equals(namespace))
+      {
+        return spec.getExtensibleRemoveExtensionNodeCommand();
+      }
+    }
+    
+    for (Iterator i = categoryProviderList.iterator(); i.hasNext(); )
+    {
+      CategoryProvider categoryProvider = (CategoryProvider)i.next();
+      for (Iterator j = categoryProvider.getCategories().iterator(); j.hasNext(); )
+      {
+        SpecificationForExtensionsSchema spec = (SpecificationForExtensionsSchema) j.next();
+        String namespaceURI = spec.getNamespaceURI();
+        if (namespaceURI != null && namespaceURI.equals(namespace))
+        {
+          return spec.getExtensibleRemoveExtensionNodeCommand();
+        }
+      }
+    }
+    
+    return null;
+  }
+  
+  public List getCategoryProviders()
+  {
+    if (nsURIProperties == null)
+    {
+      getAllExtensionsSchemasContribution();
+    }
+    
+    return categoryProviderList;
+  }
+
   /**
    * @deprecated
    */
   public ILabelProvider getLabelProvider(Element element)
-  {/*
-    String uri = element.getNamespaceURI();
-    if (uri == null)
-      uri = ""; //$NON-NLS-1$
-
-    // Didn't retrieve the config elements yet.
-    if (propertyMap == null)
-    {
-      getAllExtensionsSchemasContribution();
-    }
-
-    Object object = propertyMap.get(uri);
-    if (object instanceof ILabelProvider)
-    {
-      return (ILabelProvider) object;
-    }*/
+  {
     return null;
   }
 
diff --git a/bundles/org.eclipse.wst.xsd.ui/src-common/org/eclipse/wst/xsd/ui/internal/common/properties/sections/appinfo/SpecificationForExtensionsSchema.java b/bundles/org.eclipse.wst.xsd.ui/src-common/org/eclipse/wst/xsd/ui/internal/common/properties/sections/appinfo/SpecificationForExtensionsSchema.java
index 816bb19..e68e220 100644
--- a/bundles/org.eclipse.wst.xsd.ui/src-common/org/eclipse/wst/xsd/ui/internal/common/properties/sections/appinfo/SpecificationForExtensionsSchema.java
+++ b/bundles/org.eclipse.wst.xsd.ui/src-common/org/eclipse/wst/xsd/ui/internal/common/properties/sections/appinfo/SpecificationForExtensionsSchema.java
@@ -14,6 +14,7 @@
 
 import org.eclipse.jface.viewers.ILabelProvider;
 import org.eclipse.wst.xsd.ui.internal.common.commands.ExtensibleAddExtensionCommand;
+import org.eclipse.wst.xsd.ui.internal.common.commands.ExtensibleRemoveExtensionNodeCommand;
 
 public class SpecificationForExtensionsSchema
 {
@@ -23,7 +24,8 @@
   private String location;
   private ILabelProvider labelProvider;
   private boolean isDefaultSchema = false;
-  private ExtensibleAddExtensionCommand addActionCommand;
+  private ExtensibleAddExtensionCommand addCommand;
+  private ExtensibleRemoveExtensionNodeCommand removeCommand;
   
   /**
    * Either the workspace-relative path of the xsd file or the namespace
@@ -131,12 +133,22 @@
 
   public ExtensibleAddExtensionCommand getExtensibleAddExtensionCommand()
   {
-    return addActionCommand;
+    return addCommand;
   }
 
-  public void setExtensibleAddExtensionCommand(ExtensibleAddExtensionCommand addActionCommand)
+  public void setExtensibleAddExtensionCommand(ExtensibleAddExtensionCommand addCommand)
   {
-    this.addActionCommand = addActionCommand;
+    this.addCommand = addCommand;
+  }
+
+  public ExtensibleRemoveExtensionNodeCommand getExtensibleRemoveExtensionNodeCommand()
+  {
+    return removeCommand;
+  }
+
+  public void setExtensibleRemoveExtensionNodeCommand(ExtensibleRemoveExtensionNodeCommand removeCommand)
+  {
+    this.removeCommand = removeCommand;
   }
 
   public boolean isDefautSchema(){