Partial fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=250850.

Changes ordering of element edit factories so adopt ones (ones whose plugin id does not start with org.eclipse.jst) are always consulted first.

Changes to tag conversion factories to do similar, but doesn't currently have much affect since DTManager overrides.

Also added .options file and TraceOptions class which allows tracing of factory ordering and selection.
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/.options b/jsf/plugins/org.eclipse.jst.pagedesigner/.options
new file mode 100644
index 0000000..0b7e602
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/.options
@@ -0,0 +1,5 @@
+org.eclipse.jst.pagedesigner/debug=true
+org.eclipse.jst.pagedesigner/debug/converter/load=false
+org.eclipse.jst.pagedesigner/debug/converter/selection=false
+org.eclipse.jst.pagedesigner/debug/elementedit/load=false
+org.eclipse.jst.pagedesigner/debug/elementedit/selection=false
\ No newline at end of file
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/build.properties b/jsf/plugins/org.eclipse.jst.pagedesigner/build.properties
index a18d5dc..fdf6446 100644
--- a/jsf/plugins/org.eclipse.jst.pagedesigner/build.properties
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/build.properties
@@ -18,6 +18,7 @@
                plugin.xml,\
                schema/,\
                about.html,\
-               default.properties
+               default.properties,\
+               .options
 javacSource=1.5
-javacTarget=1.5
\ No newline at end of file
+javacTarget=1.5
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/PageDesignerTraceOptions.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/PageDesignerTraceOptions.java
new file mode 100644
index 0000000..b064770
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/PageDesignerTraceOptions.java
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 2008 Oracle 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:
+ *     Oracle Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.pagedesigner;
+
+import org.eclipse.osgi.framework.debug.FrameworkDebugOptions;
+import org.eclipse.osgi.service.debug.DebugOptions;
+
+/**
+ * Defines that standard runtime trace options for debugging. See .options file
+ * for definitions.
+ * 
+ * NOT API
+ * 
+ * @author cbateman
+ * 
+ */
+public final class PageDesignerTraceOptions
+{
+    /**
+     * True if debug tracing is enabled. Other tracing cannot be enabled unless
+     * this is enabled.
+     */
+    public static final boolean ENABLED;
+
+    /**
+     * True if tag converter ext load tracing is enabled
+     */
+    public static final boolean TRACE_CONVERTERLOAD;
+    /**
+     * True if tag converter selection tracing is enabled
+     */
+    public static final boolean TRACE_CONVERTERSELECT;
+    /**
+     * True if tag element edit ext load tracing is enabled
+     */
+    public static final boolean TRACE_ELEMENTEDITLOAD;
+    /**
+     * True if tag element edit selection tracing is enabled
+     */
+    public static final boolean TRACE_ELEMENTEDITSELECTION;
+
+    private static final String KEY_DEBUG_ENABLED = "/debug";
+    private static final String KEY_CONVERTER = KEY_DEBUG_ENABLED+"/converter";
+    private static final String KEY_CONVERTER_LOAD = KEY_CONVERTER + "/load";
+    private static final String KEY_CONVERTER_SELECTION = KEY_CONVERTER + "/selection";
+
+    private static final String KEY_ELEMENTEDIT = KEY_DEBUG_ENABLED+"/elementedit";
+    private static final String KEY_ELEMENTEDIT_LOAD = KEY_ELEMENTEDIT + "/load";
+    private static final String KEY_ELEMENTEDIT_SELECTION = KEY_ELEMENTEDIT + "/selection";
+
+    
+    static
+    {
+        final DebugOptions debugOptions = FrameworkDebugOptions.getDefault();
+        final String pluginId = PDPlugin.getPluginId();
+        ENABLED = debugOptions != null
+                && debugOptions.getBooleanOption(pluginId
+                        + KEY_DEBUG_ENABLED, false);
+
+        if (ENABLED)
+        {
+            TRACE_CONVERTERLOAD = debugOptions.getBooleanOption(
+                    pluginId + KEY_CONVERTER_LOAD, false);
+            TRACE_CONVERTERSELECT = debugOptions.getBooleanOption(
+                    pluginId + KEY_CONVERTER_SELECTION, false);
+            TRACE_ELEMENTEDITLOAD = debugOptions.getBooleanOption(
+                    pluginId + KEY_ELEMENTEDIT_LOAD, false);
+            TRACE_ELEMENTEDITSELECTION = debugOptions.getBooleanOption(
+                    pluginId + KEY_ELEMENTEDIT_SELECTION, false);
+        }
+        else
+        {
+            TRACE_CONVERTERLOAD = false;
+            TRACE_CONVERTERSELECT = false;
+            TRACE_ELEMENTEDITLOAD = false;
+            TRACE_ELEMENTEDITSELECTION = false;
+        }
+    }
+
+    /**
+     * @param message
+     */
+    public static void log(final String message)
+    {
+        System.out.println(message);
+    }
+    
+    /**
+     * @param msg A short label placed before the trace of t to show the source
+     * @param t
+     */
+    public static void log(final String msg, final Throwable t)
+    {
+        System.out.printf("%s: Exception Trace:\n\n",msg);
+        t.printStackTrace(System.out);
+        System.out.print("\n\n\n");
+    }
+
+    private PageDesignerTraceOptions()
+    {
+        // no instantiation
+    }
+}
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/ConverterFacRegistryReader.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/ConverterFacRegistryReader.java
index 147850e..b285e62 100644
--- a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/ConverterFacRegistryReader.java
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/ConverterFacRegistryReader.java
@@ -22,6 +22,7 @@
 import org.eclipse.core.runtime.Platform;
 import org.eclipse.jst.pagedesigner.IJMTConstants;
 import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.PageDesignerTraceOptions;
 
 /**
  * @author mengbo
@@ -42,38 +43,75 @@
 
 	}
 
-	private static List<IConverterFactory> readAllHandlers() {
-		List result = new ArrayList<IConverterFactory>();
-		IExtensionPoint extensionPoint = Platform.getExtensionRegistry()
-				.getExtensionPoint(PDPlugin.getPluginId(),
-						IJMTConstants.EXTENSION_POINT_PAGEDESIGNER);
-		IExtension[] extensions = extensionPoint.getExtensions();
+	private static List<IConverterFactory> readAllHandlers()
+    {
+        final List<IConverterFactory> result = new ArrayList<IConverterFactory>();
+        IExtensionPoint extensionPoint = Platform.getExtensionRegistry()
+                .getExtensionPoint(PDPlugin.getPluginId(),
+                        IJMTConstants.EXTENSION_POINT_PAGEDESIGNER);
+        IExtension[] extensions = extensionPoint.getExtensions();
 
-		for (int i = 0; i < extensions.length; i++) {
-			IExtension ext = extensions[i];
-			IConfigurationElement[] dropHandlers = ext
-					.getConfigurationElements();
+        for (int i = 0; i < extensions.length; i++)
+        {
+            IExtension ext = extensions[i];
+            IConfigurationElement[] tagConverter = ext
+                    .getConfigurationElements();
 
-			for (int j = 0; j < dropHandlers.length; j++) {
-				if (dropHandlers[j].getName().equals(
-						IJMTConstants.TAG_CONVERTER_FACTORY)) {
-					dropHandlers[j].getAttribute("class");
-					Object obj;
-					try {
-						obj = dropHandlers[j]
-								.createExecutableExtension("class");
+            for (int j = 0; j < tagConverter.length; j++)
+            {
+                final IConfigurationElement element = tagConverter[j];
 
-						if (obj instanceof IConverterFactory) {
-							result.add(obj);
-						}
-					} catch (CoreException e) {
-						// ignore the exception
-						e.printStackTrace();
-					}
-				}
-			}
-		}
-		return result;
-	}
+                if (element.getName().equals(
+                        IJMTConstants.TAG_CONVERTER_FACTORY))
+                {
+                    element.getAttribute("class");
+                    Object obj;
+                    try
+                    {
+                        obj = element.createExecutableExtension("class");
+
+                        if (element.getContributor().getName().startsWith(
+                                "org.eclipse.jst"))
+                        {
+                            if (PageDesignerTraceOptions.TRACE_CONVERTERLOAD)
+                            {
+                                PageDesignerTraceOptions.log("ConverterFacRegistryReader: Appending to list:"+obj.getClass().getName());
+                            }
+                            // push JSF tools provided ones to the end
+                            result.add((IConverterFactory) obj);
+                        }
+                        // prepend if something outside JSF tools declared it
+                        else
+                        {
+                            if (PageDesignerTraceOptions.TRACE_CONVERTERLOAD)
+                            {
+                                PageDesignerTraceOptions.log("ConverterFacRegistryReader: Prepending to list:"+obj.getClass().getName());
+                            }
+                            // this way, adopters can put their overrides
+                            // of factories with built-in support like
+                            // JSF HTML/CORE will be used first
+                            result.add(0, (IConverterFactory) obj);
+                        }
+
+                    } 
+                    catch (CoreException e)
+                    {
+                        PDPlugin.log("Problem loading tag converter extension for "+element.toString(), e);
+                    }
+                }
+            }
+        }
+
+        if (PageDesignerTraceOptions.TRACE_CONVERTERLOAD)
+        {
+            PageDesignerTraceOptions.log("\nFinal converterFactory list in order:");
+            for (final IConverterFactory factory : result)
+            {
+                PageDesignerTraceOptions.log(factory.getClass().getName());
+            }
+            PageDesignerTraceOptions.log("\n");
+        }
+        return result;
+    }
 
 }
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/ConverterFactoryRegistry.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/ConverterFactoryRegistry.java
index bcbaa37..585d8f4 100644
--- a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/ConverterFactoryRegistry.java
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/converter/ConverterFactoryRegistry.java
@@ -19,6 +19,7 @@
 import org.eclipse.jst.jsf.common.ui.internal.utils.JSFSharedImages;
 import org.eclipse.jst.jsf.core.internal.tld.CMUtil;
 import org.eclipse.jst.jsf.core.internal.tld.ITLDConstants;
+import org.eclipse.jst.pagedesigner.PageDesignerTraceOptions;
 import org.eclipse.jst.pagedesigner.converter.html.HTMLConverterFactory;
 import org.eclipse.jst.pagedesigner.converter.jsp.JSPConverterFactory;
 import org.eclipse.swt.graphics.Image;
@@ -30,116 +31,201 @@
  * @author mengbo
  * @version 1.5
  */
-public class ConverterFactoryRegistry {
-	List _factories = new ArrayList();
+public class ConverterFactoryRegistry
+{
+    List _factories = new ArrayList();
 
-	private static ConverterFactoryRegistry _instance;
+    private static ConverterFactoryRegistry _instance;
 
-	/**
-	 * 
+    /**
+	 *
 	 */
-	private ConverterFactoryRegistry() {
-		_factories.add(new JSPConverterFactory());
-		_factories.add(new HTMLConverterFactory());
-
-		List<IConverterFactory> facs = ConverterFacRegistryReader.getAllHandlers();
-		if (facs != null) {
-			for (IConverterFactory fac : facs) {
-				addFactory(fac);
-			}
-		}
-	}
-
-	/**
-	 * @param fac
-	 */
-	public void addFactory(IConverterFactory fac) {
-		_factories.add(fac);
-	}
-
-	/**
-	 * @param ele
-	 * @param mode
-	 * @param targetDocument
-	 * @return the new btag converter
-	 */
-	public ITagConverter createTagConverter(Element ele, int mode,
-			IDOMDocument targetDocument) {
-		ITagConverter converter = internalCreateTagConverter(ele, mode);
-		if (converter != null) {
-			converter.setDestDocument(targetDocument);
-		}
-		return converter;
-	}
-
-	/**
-	 * @param ele
-	 * @param mode
-	 * @return the new tag converter
-	 */
-	protected final ITagConverter internalCreateTagConverter(Element ele, int mode) {
-		String uri = CMUtil.getElementNamespaceURI(ele);
-		// first round, match uri
-		for (int i = 0, size = _factories.size(); i < size; i++) {
-			IConverterFactory fac = (IConverterFactory) _factories.get(i);
-			String facuri = fac.getSupportedURI();
-			if (facuri != null && facuri.equals(uri)) {
-				ITagConverter converter = fac.createConverter(ele, mode);
-				if (converter != null) {
-					return converter;
-				}
-			}
-		}
-		// second round
-		for (int i = 0, size = _factories.size(); i < size; i++) {
-			IConverterFactory fac = (IConverterFactory) _factories.get(i);
-			String facuri = fac.getSupportedURI();
-			if (facuri == null) {
-				ITagConverter converter = fac.createConverter(ele, mode);
-				if (converter != null) {
-					return converter;
-				}
-			}
-		}
-
-		// can't find. We need some default tag converter for it.
-		// if the tag is empty, show it as icon.
-		if (uri == null || ITLDConstants.URI_HTML.equals(uri)) {
-			// basically, for HTML or non JSP tag, directly renders it.
-			return new DumTagConverter(ele);
-		}
-        CMElementDeclaration decl = CMUtil.getElementDeclaration(ele);
-        if (decl == null) {
-        	return new DumTagConverter(ele);
+    private ConverterFactoryRegistry()
+    {
+        final List<IConverterFactory> facs = ConverterFacRegistryReader
+                .getAllHandlers();
+        if (facs != null)
+        {
+            for (final IConverterFactory fac : facs)
+            {
+                addFactory(fac);
+            }
         }
-        int contentType = decl.getContentType();
-        if (contentType == CMElementDeclaration.EMPTY) {
-        	// if the tag is empty, show it as icon.
-        	return new HiddenTagConverter(ele,
-                    new LabelProvider()
+        _factories.add(new JSPConverterFactory());
+        _factories.add(new HTMLConverterFactory());
+        
+        // TODO: this is not ideal, but until we get a better system for 
+        // doing converter factory ordering:
+        // loop through the list and place the DTManager
+    }
+
+    /**
+     * @param fac
+     */
+    public void addFactory(final IConverterFactory fac)
+    {
+        _factories.add(fac);
+    }
+
+    /**
+     * @param ele
+     * @param mode
+     * @param targetDocument
+     * @return the new btag converter
+     */
+    public ITagConverter createTagConverter(final Element ele, final int mode,
+            final IDOMDocument targetDocument)
+    {
+        final ITagConverter converter = internalCreateTagConverter(ele, mode);
+        if (converter != null)
+        {
+            converter.setDestDocument(targetDocument);
+        }
+        return converter;
+    }
+
+    /**
+     * @param ele
+     * @param mode
+     * @return the new tag converter
+     */
+    protected final ITagConverter internalCreateTagConverter(final Element ele,
+            final int mode)
+    {
+        final String uri = CMUtil.getElementNamespaceURI(ele);
+        // first round, match uri
+        for (int i = 0, size = _factories.size(); i < size; i++)
+        {
+            final IConverterFactory fac = (IConverterFactory) _factories.get(i);
+            final String facuri = fac.getSupportedURI();
+            if (facuri != null && facuri.equals(uri))
+            {
+                final ITagConverter converter = fac.createConverter(ele, mode);
+                if (converter != null)
+                {
+                    if (PageDesignerTraceOptions.TRACE_CONVERTERSELECT)
                     {
-                        public Image getImage(Object element) {
-                            return getUnknownImage();
-                        }
+                        PageDesignerTraceOptions
+                                .log("ConverterFactoryRegistry: first loop, "
+                                        + String
+                                                .format(
+                                                        "Selected converter %s for uri=%s, tagname=%s",
+                                                        converter.getClass()
+                                                                .getName(),
+                                                        uri, ele.getLocalName()));
                     }
-             );
+                    return converter;
+                }
+            }
+        }
+        // second round
+        for (int i = 0, size = _factories.size(); i < size; i++)
+        {
+            final IConverterFactory fac = (IConverterFactory) _factories.get(i);
+            final String facuri = fac.getSupportedURI();
+            if (facuri == null)
+            {
+                final ITagConverter converter = fac.createConverter(ele, mode);
+                if (converter != null)
+                {
+                    if (PageDesignerTraceOptions.TRACE_CONVERTERSELECT)
+                    {
+                        PageDesignerTraceOptions
+                                .log("ConverterFactoryRegistry: second loop, "
+                                        + String
+                                                .format(
+                                                        "Selected converter %s for uri=%s, tagname=%s",
+                                                        converter.getClass()
+                                                                .getName(),
+                                                        uri, ele.getLocalName()));
+                    }
+                    return converter;
+                }
+            }
+        }
+
+        // can't find. We need some default tag converter for it.
+        // if the tag is empty, show it as icon.
+        if (uri == null || ITLDConstants.URI_HTML.equals(uri))
+        {
+            if (PageDesignerTraceOptions.TRACE_CONVERTERSELECT)
+            {
+                PageDesignerTraceOptions
+                        .log("ConverterFactoryRegistry: factory not found, "
+                                + String
+                                        .format(
+                                                "Selected DumTagConverter for uri=%s, tagname=%s",
+                                                uri, ele.getLocalName()));
+            }
+
+            // basically, for HTML or non JSP tag, directly renders it.
+            return new DumTagConverter(ele);
+        }
+        final CMElementDeclaration decl = CMUtil.getElementDeclaration(ele);
+        if (decl == null)
+        {
+            if (PageDesignerTraceOptions.TRACE_CONVERTERSELECT)
+            {
+                PageDesignerTraceOptions
+                        .log("ConverterFactoryRegistry: factory and decl not found, "
+                                + String
+                                        .format(
+                                                "Selected DumTagConverter for uri=%s, tagname=%s",
+                                                uri, ele.getLocalName()));
+            }
+            return new DumTagConverter(ele);
+        }
+        final int contentType = decl.getContentType();
+        if (contentType == CMElementDeclaration.EMPTY)
+        {
+            if (PageDesignerTraceOptions.TRACE_CONVERTERSELECT)
+            {
+                PageDesignerTraceOptions
+                        .log("ConverterFactoryRegistry: factory not found, content is EMPTY, "
+                                + String
+                                        .format(
+                                                "Selected HiddenTagConverter with UnknownImage for uri=%s, tagname=%s",
+                                                uri, ele.getLocalName()));
+            }
+
+            // if the tag is empty, show it as icon.
+            return new HiddenTagConverter(ele, new LabelProvider()
+            {
+                @Override
+                public Image getImage(final Object element)
+                {
+                    return getUnknownImage();
+                }
+            });
+        }
+        if (PageDesignerTraceOptions.TRACE_CONVERTERSELECT)
+        {
+            PageDesignerTraceOptions
+                    .log("ConverterFactoryRegistry: fall-through to default case, "
+                            + String
+                                    .format(
+                                            "Selected DefaultUnknownTagConverter with UnknownImage for uri=%s, tagname=%s",
+                                            uri, ele.getLocalName()));
         }
         return new DefaultUnknownTagConverter(ele, mode);
 
-	}
+    }
 
-	Image getUnknownImage() {
-		return JSFUICommonPlugin.getDefault().getImage(
-				JSFSharedImages.DEFAULT_PALETTE_TAG_IMG);
-	}
+    private static Image getUnknownImage()
+    {
+        return JSFUICommonPlugin.getDefault().getImage(
+                JSFSharedImages.DEFAULT_PALETTE_TAG_IMG);
+    }
 
-	/**
-	 * @return the singleton instance of the registry
-	 */ 
-	public static ConverterFactoryRegistry getInstance() {
-		if (_instance == null) {
-			_instance = new ConverterFactoryRegistry();
-		}
-		return _instance;
-	}
+    /**
+     * @return the singleton instance of the registry
+     */
+    public synchronized static ConverterFactoryRegistry getInstance()
+    {
+        if (_instance == null)
+        {
+            _instance = new ConverterFactoryRegistry();
+        }
+        return _instance;
+    }
 }
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/ElementEditFacRegistryReader.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/ElementEditFacRegistryReader.java
index e0e1b7b..f8e821e 100644
--- a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/ElementEditFacRegistryReader.java
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/ElementEditFacRegistryReader.java
@@ -22,6 +22,7 @@
 import org.eclipse.core.runtime.Platform;
 import org.eclipse.jst.pagedesigner.IJMTConstants;
 import org.eclipse.jst.pagedesigner.PDPlugin;
+import org.eclipse.jst.pagedesigner.PageDesignerTraceOptions;
 
 /**
  * @author mengbo
@@ -41,38 +42,79 @@
 		return Collections.unmodifiableList(_handlers);
 	}
 
-	private static List<IElementEditFactory> readAllHandlers() {
-		List result = new ArrayList();
-		IExtensionPoint extensionPoint = Platform.getExtensionRegistry()
-				.getExtensionPoint(PDPlugin.getPluginId(),
-						IJMTConstants.EXTENSION_POINT_PAGEDESIGNER);
-		IExtension[] extensions = extensionPoint.getExtensions();
+	private static List<IElementEditFactory> readAllHandlers()
+    {
+        List<IElementEditFactory> result = new ArrayList<IElementEditFactory>();
+        IExtensionPoint extensionPoint = Platform.getExtensionRegistry()
+                .getExtensionPoint(PDPlugin.getPluginId(),
+                        IJMTConstants.EXTENSION_POINT_PAGEDESIGNER);
+        IExtension[] extensions = extensionPoint.getExtensions();
 
-		for (int i = 0; i < extensions.length; i++) {
-			IExtension ext = extensions[i];
-			IConfigurationElement[] dropHandlers = ext
-					.getConfigurationElements();
+        for (int i = 0; i < extensions.length; i++)
+        {
+            IExtension ext = extensions[i];
+            IConfigurationElement[] elementEditElement = ext
+                    .getConfigurationElements();
 
-			for (int j = 0; j < dropHandlers.length; j++) {
-				if (dropHandlers[j].getName().equals(
-						IJMTConstants.ELEMENT_EDIT_FACTORY)) {
-					dropHandlers[j].getAttribute("class");
-					Object obj;
-					try {
-						obj = dropHandlers[j]
-								.createExecutableExtension("class");
+            for (int j = 0; j < elementEditElement.length; j++)
+            {
+                final IConfigurationElement element = elementEditElement[j];
+                if (element.getName().equals(
+                        IJMTConstants.ELEMENT_EDIT_FACTORY))
+                {
+                    elementEditElement[j].getAttribute("class");
+                    Object obj;
+                    try
+                    {
+                        obj = elementEditElement[j]
+                                .createExecutableExtension("class");
 
-						if (obj instanceof IElementEditFactory) {
-							result.add(obj);
-						}
-					} catch (CoreException e) {
-						// ignore the exception
-						e.printStackTrace();
-					}
-				}
-			}
-		}
-		return result;
-	}
+                        // TODO: we need a policy based solution here,
+                        // but this will do for now
+                        if (obj instanceof IElementEditFactory)
+                        {
+                            if (element.getContributor().getName().startsWith("org.eclipse.jst"))
+                            {
+                                if (PageDesignerTraceOptions.TRACE_ELEMENTEDITLOAD)
+                                {
+                                    PageDesignerTraceOptions.log("ElementEditFacRegistryReader: Appending to list:"+obj.getClass().getName());
+                                }
+                                // push JSF tools provided ones to the end
+                                result.add((IElementEditFactory) obj);
+                            }
+                            // prepend if something outside JSF tools declared it
+                            else
+                            {
+                                if (PageDesignerTraceOptions.TRACE_ELEMENTEDITLOAD)
+                                {
+                                    PageDesignerTraceOptions.log("ElementEditFacRegistryReader: Prepending to list:"+obj.getClass().getName());
+                                }
+                                // this way, adopters can put their overrides
+                                // of factories with built-in support like
+                                // JSF HTML/CORE will be used first
+                                result.add(0, (IElementEditFactory) obj);
+                            }
+                        }
+                    } catch (CoreException e)
+                    {
+                        PDPlugin.log("Problem loading element edit extension for "+element.toString(), e);
+                    }
+                }
+            }
+        }
+        
+
+        if (PageDesignerTraceOptions.TRACE_ELEMENTEDITLOAD)
+        {
+            PageDesignerTraceOptions.log("\nFinal elementEditFactory list in order:");
+            for (final IElementEditFactory factory : result)
+            {
+                PageDesignerTraceOptions.log(factory.getClass().getName());
+            }
+            PageDesignerTraceOptions.log("\n");
+        }
+
+        return result;
+    }
 
 }
diff --git a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/ElementEditFactoryRegistry.java b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/ElementEditFactoryRegistry.java
index 7ca7daf..6a24d82 100644
--- a/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/ElementEditFactoryRegistry.java
+++ b/jsf/plugins/org.eclipse.jst.pagedesigner/src/org/eclipse/jst/pagedesigner/elementedit/ElementEditFactoryRegistry.java
@@ -16,6 +16,7 @@
 
 import org.eclipse.jst.jsf.common.dom.TagIdentifier;
 import org.eclipse.jst.jsf.core.internal.tld.TagIdentifierFactory;
+import org.eclipse.jst.pagedesigner.PageDesignerTraceOptions;
 import org.eclipse.jst.pagedesigner.elementedit.html.HTMLElementEditFactory;
 import org.eclipse.jst.pagedesigner.elementedit.jsp.JSPElementEditFactory;
 import org.w3c.dom.Element;
@@ -24,93 +25,122 @@
  * @author mengbo
  * @version 1.5
  */
-public class ElementEditFactoryRegistry {
-	List _factories = new ArrayList();
+public class ElementEditFactoryRegistry
+{
+    List _factories = new ArrayList();
 
-	private static ElementEditFactoryRegistry _instance;
-
-	/**
-	 * 
-	 */
-	private ElementEditFactoryRegistry() {
-		addFactory(new HTMLElementEditFactory());
-        addFactory(new JSPElementEditFactory());
-
-		List<IElementEditFactory> facs = 
-		    ElementEditFacRegistryReader.getAllHandlers();
-
-		if (facs != null) 
-		{
-			for (IElementEditFactory fac : facs) 
-			{
-				addFactory(fac);
-			}
-		}
-	}
-
-	/**
-	 * Add a factory to list available.
-	 * 
-	 * @param fac
-	 */
-	public void addFactory(IElementEditFactory fac) {
-		_factories.add(fac);
-	}
+    private static ElementEditFactoryRegistry _instance;
 
     /**
-     * @param tagIdentifier 
-     * @return an IElementEdit constructed for the tag uniquely identified
-     * by the ns uri (tag uri for JSP tags) and tagName (element name) or null
-     * if the system can't create one.
+	 *
+	 */
+    private ElementEditFactoryRegistry()
+    {
+        final List<IElementEditFactory> facs = ElementEditFacRegistryReader
+                .getAllHandlers();
+
+        if (facs != null)
+        {
+            for (final IElementEditFactory fac : facs)
+            {
+                addFactory(fac);
+            }
+        }
+        addFactory(new HTMLElementEditFactory());
+        addFactory(new JSPElementEditFactory());
+    }
+
+    /**
+     * Add a factory to list available.
+     *
+     * @param fac
+     */
+    public void addFactory(final IElementEditFactory fac)
+    {
+        _factories.add(fac);
+    }
+
+    /**
+     * @param tagIdentifier
+     * @return an IElementEdit constructed for the tag uniquely identified by
+     *         the ns uri (tag uri for JSP tags) and tagName (element name) or
+     *         null if the system can't create one.
      */
     public IElementEdit createElementEdit(final TagIdentifier tagIdentifier)
     {
         final String uri = tagIdentifier.getUri();
-        
+
         // first round, match uri
-        for (int i = 0, size = _factories.size(); i < size; i++) {
-            IElementEditFactory fac = (IElementEditFactory) _factories.get(i);
-            String facuri = fac.getSupportedURI();
-            if (facuri != null && facuri.equals(uri)) {
-                IElementEdit elementEdit = fac.createElementEdit(tagIdentifier);
-                if (elementEdit != null) {
+        for (int i = 0, size = _factories.size(); i < size; i++)
+        {
+            final IElementEditFactory fac = (IElementEditFactory) _factories.get(i);
+            final String facuri = fac.getSupportedURI();
+            if (facuri != null && facuri.equals(uri))
+            {
+                final IElementEdit elementEdit = fac.createElementEdit(tagIdentifier);
+                if (elementEdit != null)
+                {
+                    if (PageDesignerTraceOptions.TRACE_ELEMENTEDITSELECTION)
+                    {
+                        PageDesignerTraceOptions.log("ElementEditFactoryRegistry: first loop, "+
+                                String.format("Selected %s for uri=%s, tagname=%s", elementEdit.getClass().getName(),uri, tagIdentifier.getTagName()));
+                    }
                     return elementEdit;
                 }
             }
         }
         // second round
-        for (int i = 0, size = _factories.size(); i < size; i++) {
-            IElementEditFactory fac = (IElementEditFactory) _factories.get(i);
-            String facuri = fac.getSupportedURI();
-            if (facuri == null) {
-                IElementEdit elementEdit = fac.createElementEdit(tagIdentifier);
-                if (elementEdit != null) {
+        for (int i = 0, size = _factories.size(); i < size; i++)
+        {
+            final IElementEditFactory fac = (IElementEditFactory) _factories.get(i);
+            final String facuri = fac.getSupportedURI();
+            if (facuri == null)
+            {
+                final IElementEdit elementEdit = fac.createElementEdit(tagIdentifier);
+                if (elementEdit != null)
+                {
+                    if (PageDesignerTraceOptions.TRACE_ELEMENTEDITSELECTION)
+                    {
+                        PageDesignerTraceOptions.log("ElementEditFactoryRegistry: second loop, "+
+                                String.format("Selected %s for uri=%s, tagname=%s", elementEdit.getClass().getName(),uri, tagIdentifier.getTagName()));
+                    }
                     return elementEdit;
                 }
             }
         }
+
+        if (PageDesignerTraceOptions.TRACE_ELEMENTEDITSELECTION)
+        {
+            PageDesignerTraceOptions.log("ElementEditFactoryRegistry: no element edit found, returning null for "+
+                    String.format("uri=%s, name=%s", tagIdentifier.getUri(), tagIdentifier.getTagName()));
+        }
+
         return null;
     }
-    
-	/**
-     * Convenience method for createElementEdit(uri, tagName) that takes
-     * a tag element.
-     * 
-	 * @param ele
-	 * @return an element edit
-	 */
-	public IElementEdit createElementEdit(Element ele) {
-		final TagIdentifier tagIdentifier = TagIdentifierFactory.createDocumentTagWrapper(ele);
-        return createElementEdit(tagIdentifier);
-	}
 
-	/**
-	 * @return the single instance of the factory registry
-	 */
-	public static ElementEditFactoryRegistry getInstance() {
-		if (_instance == null) {
-			_instance = new ElementEditFactoryRegistry();
-		}
-		return _instance;
-	}
+    /**
+     * Convenience method for createElementEdit(uri, tagName) that takes a tag
+     * element.
+     *
+     * @param ele
+     * @return an element edit
+     */
+    public IElementEdit createElementEdit(final Element ele)
+    {
+        final TagIdentifier tagIdentifier = TagIdentifierFactory
+                .createDocumentTagWrapper(ele);
+        return createElementEdit(tagIdentifier);
+    }
+
+    /**
+     * @return the single instance of the factory registry
+     */
+    public synchronized static ElementEditFactoryRegistry getInstance()
+    {
+        if (_instance == null)
+        {
+            _instance = new ElementEditFactoryRegistry();
+        }
+        return _instance;
+    }
 }