Ok, so I've spent some time this morning implementing a way of
separating extensions from the underlying Axiom implementation.  The
mechanism is surprisingly simple.  I haven't checked this in yet but
will do so if no one cries Stop!

I've attached the patch for review.

To create an extension element, a developer would extend either
ElementWrapper or ExtensibleElementWrapper.

  public class FooElement extends ElementWrapper {
    protected FooElement(Element internal) {
      super(internal);
    }
    protected FooElement(Factory factory) {
      super(factory, TestExtensionFactory.FOO);
    }
    public String getFoo() {
      return getText();
    }
    public void setFoo(String foo) {
      setText(foo);
    }
  }

Then register an ExtensionFactory like before, but the methods have
changed a bit:

  public class TestExtensionFactory implements ExtensionFactory {

    public static final QName FOO = new QName("urn:foo", "foo");

    @SuppressWarnings("unchecked")
    public <T extends Element> T getElementWrapper(Element internal) {
      QName qname = internal.getQName();
      if (qname.equals(FOO)) return (T)new FooElement(internal);
      return (T) internal;
    }
    public List<String> getNamespaces() {
      return java.util.Arrays.asList(new String[] {"urn:foo"});
    }
    public boolean handlesNamespace(String namespace) {
      return namespace.equals("urn:foo");
    }
  }

We can then use FooElement seamlessly with the core API

    Abdera abdera = new Abdera();
    Factory factory = abdera.getFactory();
    factory.registerExtension(new TestExtensionFactory());
    Entry entry = factory.newEntry();
    FooElement foo = entry.addExtension(TestExtensionFactory.FOO);
    foo.setFoo("testing");

Or...

    Abdera abdera = new Abdera();
    Factory factory = abdera.getFactory();
    factory.registerExtension(new TestExtensionFactory());

    String s = "<foo xmlns='urn:foo'>testing</foo>";
    ByteArrayInputStream in = new ByteArrayInputStream(s.getBytes());

    Parser parser = abdera.getParser();
    ParserOptions options = parser.getDefaultParserOptions();
    options.setFactory(factory);

    Document<FooElement> doc = parser.parse(in, null, options);
    FooElement foo = doc.getRoot();
    System.out.println(foo.getFoo());

Thoughts?

- James
Index: 
/home/jasnell/workspaces/abdera/core/src/main/java/org/apache/abdera/factory/ExtensionFactory.java
===================================================================
--- 
/home/jasnell/workspaces/abdera/core/src/main/java/org/apache/abdera/factory/ExtensionFactory.java
  (revision 467053)
+++ 
/home/jasnell/workspaces/abdera/core/src/main/java/org/apache/abdera/factory/ExtensionFactory.java
  (working copy)
@@ -17,13 +17,10 @@
 */
 package org.apache.abdera.factory;
 
-import javax.xml.namespace.QName;
+import java.util.List;
 
-import org.apache.abdera.model.Base;
 import org.apache.abdera.model.Element;
 
-import java.util.List;
-
 /**
  * <p>
  *   Extension Factories are used to provide a means of dynamically resolving
@@ -67,16 +64,5 @@
    */
   List<String> getNamespaces();
 
-  /**
-   * Called by the Factory implementaton to create an instance of the 
-   * extension element.  If parent is not null, the new element will 
-   * be automatically added as a child of the parent.
-   * 
-   * @param qname the QName of the extension element
-   * @param parent the Parent of the extension element
-   * @param factory the Factory
-   * @return ExtensionElement The created ExtensionElement
-   */
-  <T extends Element>T newExtensionElement(QName qname, Base parent, Factory 
factory);
-
+  <T extends  Element>T getElementWrapper(Element internal);
 }
Index: 
/home/jasnell/workspaces/abdera/core/src/main/java/org/apache/abdera/factory/ExtensionFactoryMap.java
===================================================================
--- 
/home/jasnell/workspaces/abdera/core/src/main/java/org/apache/abdera/factory/ExtensionFactoryMap.java
       (revision 0)
+++ 
/home/jasnell/workspaces/abdera/core/src/main/java/org/apache/abdera/factory/ExtensionFactoryMap.java
       (revision 0)
@@ -0,0 +1,86 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.factory;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+
+import javax.xml.namespace.QName;
+
+import org.apache.abdera.model.Base;
+import org.apache.abdera.model.Element;
+
+public class ExtensionFactoryMap 
+  implements ExtensionFactory {
+
+  private final List<ExtensionFactory> factories;
+  private final Map<Element,Element> wrappers;
+  
+  public ExtensionFactoryMap(List<ExtensionFactory> factories) {
+    this.factories = factories;
+    this.wrappers = new HashMap<Element,Element>();
+  }
+
+  @SuppressWarnings("unchecked")
+  public <T extends Element> T getElementWrapper(Element internal) {
+    T t = (T)wrappers.get(internal);
+    if (t == null) {
+      for (ExtensionFactory factory : factories) {
+        t = factory.getElementWrapper(internal);
+        if (t != null) {
+          wrappers.put(internal, t);
+          return t;
+        }
+      }
+      t = (T) internal;
+    }
+    return t;
+  }
+  
+  public void setElementWrapper(Element internal, Element wrapper) {
+    wrappers.put(internal, wrapper);
+  }
+
+  public List<String> getNamespaces() {
+    List<String> ns = new ArrayList<String>();
+    for (ExtensionFactory factory : factories) {
+      ns.addAll(factory.getNamespaces());
+    }
+    return ns;
+  }
+
+  public boolean handlesNamespace(String namespace) {
+    for (ExtensionFactory factory : factories) {
+      if (factory.handlesNamespace(namespace)) return true;
+    }
+    return false;
+  }
+
+  public <T extends Element> T newExtensionElement(
+    QName qname, 
+    Base parent, 
+    Factory factory) {
+      return null;
+  }
+
+  public List<ExtensionFactory> getFactories() {
+    return factories;
+  }
+}
Index: 
/home/jasnell/workspaces/abdera/core/src/main/java/org/apache/abdera/factory/Factory.java
===================================================================
--- 
/home/jasnell/workspaces/abdera/core/src/main/java/org/apache/abdera/factory/Factory.java
   (revision 467053)
+++ 
/home/jasnell/workspaces/abdera/core/src/main/java/org/apache/abdera/factory/Factory.java
   (working copy)
@@ -608,13 +608,6 @@
   Div newDiv(Base parent);
 
   /**
-   * Registers an extension implementation class for this Factory instance only
-   * @param qname The XML QName of the extension element to register
-   * @param impl The implementation class for the extension element
-   */
-  <T extends Base>void registerExtension(QName qname, Class impl);
-  
-  /**
    * Registers an extension factory for this Factory instance only
    * @param extensionFactory An ExtensionFactory instance 
    */
@@ -641,4 +634,9 @@
    * Generate a new random UUID URI 
    */
   String newUuidUri();
+  
+  /**
+   * Set an element wrapper
+   */
+  void setElementWrapper(Element element, Element wrapper);
 }
Index: 
/home/jasnell/workspaces/abdera/core/src/main/java/org/apache/abdera/model/ElementWrapper.java
===================================================================
--- 
/home/jasnell/workspaces/abdera/core/src/main/java/org/apache/abdera/model/ElementWrapper.java
      (revision 0)
+++ 
/home/jasnell/workspaces/abdera/core/src/main/java/org/apache/abdera/model/ElementWrapper.java
      (revision 0)
@@ -0,0 +1,202 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.model;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Writer;
+import java.util.List;
+import java.util.Locale;
+
+import javax.xml.namespace.QName;
+
+import org.apache.abdera.factory.Factory;
+import org.apache.abdera.util.iri.IRI;
+import org.apache.abdera.util.iri.IRISyntaxException;
+
+public abstract class ElementWrapper 
+  implements Element {
+
+  private final Element internal;
+  
+  protected ElementWrapper(
+    Element internal) {
+      this.internal = internal;
+  }
+  
+  protected ElementWrapper(Factory factory, QName qname) {
+    Element el = factory.newElement(qname);
+    internal = (el instanceof ElementWrapper) ?
+      ((ElementWrapper)el).getInternal() : el;
+    factory.setElementWrapper(internal, this);
+  }
+
+  public void addComment(
+    String value) {
+      internal.addComment(value);
+  }
+
+  public Object clone() {
+    try {
+      return super.clone();
+    } catch (CloneNotSupportedException e) {
+      // won't happen
+      return null;
+    }
+  }
+
+  public void declareNS(String uri, String prefix) {
+    internal.declareNS(uri, prefix);
+  }
+
+  public void discard() {
+    internal.discard();
+  }
+
+  public List<QName> getAttributes() {
+    return internal.getAttributes();
+  }
+
+  public String getAttributeValue(QName qname) {
+    return internal.getAttributeValue(qname);
+  }
+
+  public String getAttributeValue(String name) {
+    return internal.getAttributeValue(name);
+  }
+
+  public IRI getBaseUri() throws IRISyntaxException {
+    return internal.getBaseUri();
+  }
+
+  public <T extends Element> Document<T> getDocument() {
+    return internal.getDocument();
+  }
+
+  public List<QName> getExtensionAttributes() {
+    return internal.getExtensionAttributes();
+  }
+
+  public Factory getFactory() {
+    return internal.getFactory();
+  }
+
+  public <T extends Element> T getFirstChild() {
+    return internal.getFirstChild();
+  }
+
+  public <T extends Element> T getFirstChild(QName qname) {
+    return internal.getFirstChild(qname);
+  }
+
+  public String getLanguage() {
+    return internal.getLanguage();
+  }
+
+  public Locale getLocale() {
+    return internal.getLocale();
+  }
+
+  public <T extends Element> T getNextSibling() {
+    return internal.getNextSibling();
+  }
+
+  public <T extends Element> T getNextSibling(QName qname) {
+    return internal.getNextSibling(qname);
+  }
+
+  public <T extends Base> T getParentElement() {
+    return internal.getParentElement();
+  }
+
+  public <T extends Element> T getPreviousSibling() {
+    return internal.getPreviousSibling();
+  }
+
+  public <T extends Element> T getPreviousSibling(QName qname) {
+    return internal.getPreviousSibling(qname);
+  }
+
+  public QName getQName() {
+    return internal.getQName();
+  }
+
+  public IRI getResolvedBaseUri() throws IRISyntaxException {
+    return internal.getResolvedBaseUri();
+  }
+
+  public String getText() {
+    return internal.getText();
+  }
+
+  public void removeAttribute(QName qname) {
+    internal.removeAttribute(qname);
+  }
+
+  public void setAttributeValue(QName qname, String value) {
+    internal.setAttributeValue(qname, value);
+  }
+
+  public void setAttributeValue(String name, String value) {
+    internal.setAttributeValue(name, value);
+  }
+
+  public void setBaseUri(IRI base) {
+    internal.setBaseUri(base);
+  }
+
+  public void setBaseUri(String base) throws IRISyntaxException {
+    internal.setBaseUri(base);
+  }
+
+  public void setLanguage(String language) {
+    internal.setLanguage(language);
+  }
+
+  public void setParentElement(Element parent) {
+    internal.setParentElement(parent);
+  }
+
+  public void setText(String text) {
+    internal.setText(text);
+  }
+
+  public void writeTo(OutputStream out) throws IOException {
+    internal.writeTo(out);
+  }
+
+  public void writeTo(Writer writer) throws IOException {
+    internal.writeTo(writer);
+  }
+  
+  public boolean equals(Object other) {
+    return internal.equals(other);
+  }
+  
+  public String toString() {
+    return internal.toString();
+  }
+  
+  public int hashCode() {
+    return internal.hashCode();
+  }
+
+  public Element getInternal() {
+    return internal;
+  }
+}
Index: 
/home/jasnell/workspaces/abdera/core/src/main/java/org/apache/abdera/model/ExtensibleElementWrapper.java
===================================================================
--- 
/home/jasnell/workspaces/abdera/core/src/main/java/org/apache/abdera/model/ExtensibleElementWrapper.java
    (revision 0)
+++ 
/home/jasnell/workspaces/abdera/core/src/main/java/org/apache/abdera/model/ExtensibleElementWrapper.java
    (revision 0)
@@ -0,0 +1,90 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.model;
+
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+import org.apache.abdera.factory.Factory;
+
+public class ExtensibleElementWrapper 
+  extends ElementWrapper 
+  implements ExtensibleElement {
+
+  protected ExtensibleElementWrapper(Element internal) {
+    super(internal);
+  }
+  
+  public ExtensibleElementWrapper(Factory factory, QName qname) {
+    super(factory, qname);
+  }
+
+  private ExtensibleElement getExtInternal() {
+    return (ExtensibleElement) getInternal();
+  }
+  
+  public void addExtension(Element extension) {
+    getExtInternal().addExtension(extension);
+  }
+
+  public <T extends Element> T addExtension(QName qname) {
+    return getExtInternal().addExtension(qname);
+  }
+
+  public <T extends Element> T addExtension(String namespace, String 
localPart, String prefix) {
+    return getExtInternal().addExtension(namespace, localPart, prefix);
+  }
+
+  public Element addSimpleExtension(QName qname, String value) {
+    return getExtInternal().addSimpleExtension(qname, value);
+  }
+
+  public Element addSimpleExtension(String namespace, String localPart, String 
prefix, String value) {
+    return getExtInternal().addSimpleExtension(namespace, localPart, prefix, 
value);
+  }
+
+  public <T extends Element> T getExtension(QName qname) {
+    return getExtInternal().getExtension(qname);
+  }
+
+  public <T extends Element> T getExtension(Class<T> _class) {
+    return getExtInternal().getExtension(_class);
+  }
+
+  public List<Element> getExtensions() {
+    return getExtInternal().getExtensions();
+  }
+
+  public List<Element> getExtensions(String uri) {
+    return getExtInternal().getExtensions(uri);
+  }
+
+  public <T extends Element> List<T> getExtensions(QName qname) {
+    return getExtInternal().getExtensions(qname);
+  }
+
+  public String getSimpleExtension(QName qname) {
+    return getExtInternal().getSimpleExtension(qname);
+  }
+
+  public String getSimpleExtension(String namespace, String localPart, String 
prefix) {
+    return getExtInternal().getSimpleExtension(namespace, localPart, prefix);
+  }
+  
+}
Index: 
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/FOMDocument.java
===================================================================
--- 
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/FOMDocument.java
 (revision 467052)
+++ 
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/FOMDocument.java
 (working copy)
@@ -30,6 +30,7 @@
 import org.apache.abdera.factory.Factory;
 import org.apache.abdera.model.Document;
 import org.apache.abdera.model.Element;
+import org.apache.abdera.model.ElementWrapper;
 import org.apache.abdera.util.iri.IRI;
 import org.apache.abdera.util.iri.IRISyntaxException;
 import org.apache.axiom.om.OMComment;
@@ -90,11 +91,16 @@
 
   @SuppressWarnings("unchecked")
   public T getRoot() {  
-    return (T)this.getOMDocumentElement();
+    FOMFactory factory = (FOMFactory) getFactory();
+    return factory.getElementWrapper((T)this.getOMDocumentElement());
   }
 
   public void setRoot(T root) {
-    this.setOMDocumentElement((OMElement) root);
+    if (root instanceof OMElement) {
+      this.setOMDocumentElement((OMElement) root);
+    } else if (root instanceof ElementWrapper) {
+      this.setOMDocumentElement((OMElement) 
((ElementWrapper)root).getInternal());
+    }
   }
 
   public IRI getBaseUri() {
Index: 
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/FOMExtensibleElement.java
===================================================================
--- 
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/FOMExtensibleElement.java
        (revision 467052)
+++ 
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/FOMExtensibleElement.java
        (working copy)
@@ -22,7 +22,9 @@
 import javax.xml.namespace.QName;
 
 import org.apache.abdera.model.Element;
+import org.apache.abdera.model.ElementWrapper;
 import org.apache.abdera.model.ExtensibleElement;
+import org.apache.abdera.parser.stax.util.FOMElementIteratorWrapper;
 import org.apache.abdera.parser.stax.util.FOMExtensionIterator;
 import org.apache.abdera.parser.stax.util.FOMList;
 import org.apache.axiom.om.OMContainer;
@@ -80,7 +82,10 @@
 
   @SuppressWarnings("unchecked")
   public <T extends Element>List<T> getExtensions(QName qname) {
-    return new FOMList<T>(getChildrenWithName(qname));
+    FOMFactory factory = (FOMFactory) this.getFactory();
+    return new FOMList<T>(
+      new FOMElementIteratorWrapper(
+        factory,getChildrenWithName(qname)));
   }
 
   @SuppressWarnings("unchecked")
@@ -85,10 +90,16 @@
 
   @SuppressWarnings("unchecked")
   public <T extends Element>T getExtension(QName qname) {
-    return (T) this.getFirstChildWithName(qname);
+    FOMFactory factory = (FOMFactory) getFactory();
+    T t = (T) this.getFirstChildWithName(qname);
+    return (T) ((t != null) ? factory.getElementWrapper(t) : null);
   }
   
   public void addExtension(Element extension) {
+    if (extension instanceof ElementWrapper) {
+      ElementWrapper wrapper = (ElementWrapper) extension;
+      extension = wrapper.getInternal();
+    }
     addChild((OMElement)extension);
   }
   
Index: 
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/FOMExtensionFactory.java
===================================================================
--- 
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/FOMExtensionFactory.java
 (revision 467052)
+++ 
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/FOMExtensionFactory.java
 (working copy)
@@ -1,37 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  The ASF licenses this file to You
-* under the Apache License, Version 2.0 (the "License"); you may not
-* use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.  For additional information regarding
-* copyright in this work, please see the NOTICE file in the top level
-* directory of this distribution.
-*/
-package org.apache.abdera.parser.stax;
-
-import javax.xml.namespace.QName;
-
-import org.apache.abdera.factory.ExtensionFactory;
-import org.apache.abdera.factory.Factory;
-import org.apache.abdera.model.Base;
-import org.apache.abdera.model.Element;
-import org.apache.axiom.om.OMXMLParserWrapper;
-
-
-public interface FOMExtensionFactory extends ExtensionFactory {
-
-  public <T extends Element>T newExtensionElement(
-    QName qname,
-    Base parent,
-    Factory factory,
-    OMXMLParserWrapper parserWrapper);
-
-}
Index: 
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/FOMFactory.java
===================================================================
--- 
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/FOMFactory.java
  (revision 467052)
+++ 
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/FOMFactory.java
  (working copy)
@@ -18,10 +18,7 @@
 package org.apache.abdera.parser.stax;
  
 import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
 import javax.activation.MimeType;
 import javax.activation.MimeTypeParseException;
@@ -29,6 +26,7 @@
 
 import org.apache.abdera.Abdera;
 import org.apache.abdera.factory.ExtensionFactory;
+import org.apache.abdera.factory.ExtensionFactoryMap;
 import org.apache.abdera.factory.Factory;
 import org.apache.abdera.model.Base;
 import org.apache.abdera.model.Categories;
@@ -67,10 +65,9 @@
 
 public class FOMFactory 
   extends OMLinkedListImplFactory 
-  implements Factory, Constants, ExtensionFactory, FOMExtensionFactory {
+  implements Factory, Constants, ExtensionFactory {
 
-  private final Map<QName,Class> extensions;
-  private final List<ExtensionFactory> factories;
+  private final ExtensionFactoryMap factoriesMap;
   
   public FOMFactory() {
     this(new Abdera());
@@ -77,12 +74,12 @@
   }
   
   public FOMFactory(Abdera abdera) {
-    List<ExtensionFactory> f= 
abdera.getConfiguration().getExtensionFactories();
-    this.factories = (f != null) ? 
-      new ArrayList<ExtensionFactory>(f) :
-      new ArrayList<ExtensionFactory>();
-    this.factories.add(this);
-    this.extensions = Collections.synchronizedMap(new HashMap<QName,Class>());
+    List<ExtensionFactory> f= 
+      abdera.getConfiguration().getExtensionFactories();
+    factoriesMap = new ExtensionFactoryMap(
+      (f != null) ? 
+        new ArrayList<ExtensionFactory>(f) :
+        new ArrayList<ExtensionFactory>());
   }
   
   public Parser newParser() {
@@ -404,11 +401,11 @@
   public Element newElement(
     QName qname, 
     Base parent) {
-      return new FOMExtensibleElement(qname, (OMContainer)parent,this);
+      return newExtensionElement(qname, parent);
   }
   
   public Element newExtensionElement(QName qname) {
-    return newExtensionElement(qname, (Base)null);
+    return newExtensionElement(qname, (OMContainer)null);
   }
   
   public Element newExtensionElement(
@@ -420,11 +417,14 @@
   private Element newExtensionElement(
     QName qname, 
     OMContainer parent) {
-      return newExtensionElement(qname, parent, null);
+      String ns = qname.getNamespaceURI();
+      Element el = newExtensionElement(qname, parent, null);
+      return (ATOM_NS.equals(ns) || APP_NS.equals(ns)) ?
+        el : factoriesMap.getElementWrapper(el);
   }
 
   private List<ExtensionFactory> getExtensionFactories() {
-    return factories;
+    return factoriesMap.getFactories();
   }
   
   @SuppressWarnings("unchecked")
@@ -432,27 +432,11 @@
     QName qname,
     OMContainer parent,
     OMXMLParserWrapper parserWrapper) {
-    Element element = null;
-    List<ExtensionFactory> factories = getExtensionFactories();
-    for (ExtensionFactory factory : factories) {
-      if (factory instanceof FOMExtensionFactory &&
-        factory.handlesNamespace(qname.getNamespaceURI())) {
-        if (parserWrapper != null) {
-          element = ((FOMExtensionFactory)factory).newExtensionElement(
-            qname, (Base)parent, this, parserWrapper);
-        } else {
-          element = factory.newExtensionElement(qname, (Base)parent, this); 
-        }
-      }
-    }
-    if (element == null) {
-      if (parserWrapper == null) {
-        element = new FOMExtensibleElement(qname, parent, this);
-      } else {
-        element = new FOMExtensibleElement(qname, parent, this, parserWrapper);
-      }
-    }
-    return element;
+    Element element = (parserWrapper == null) ?
+      new FOMExtensibleElement(qname, parent, this) :
+      new FOMExtensibleElement(qname, parent, this, parserWrapper);
+    //return factoriesMap.getElementWrapper(element);
+      return element;
   }
   
   public Control newControl() {
@@ -711,7 +695,9 @@
         element = new FOMDateTime(qname.getLocalPart(), namespace, parent, 
factory);
       } else if (parent instanceof ExtensibleElement || 
                  parent instanceof Document) {
-        element = (OMElement) newExtensionElement(qname, parent);
+        //element = (OMElement) newExtensionElement(qname, parent);
+        element = (OMElement) new FOMExtensibleElement(
+          qname.getLocalPart(), namespace, parent, this);
       }
       return element;
     }
@@ -784,7 +770,8 @@
     } else if (EDITED.equals(qname)) {
       element = (OMElement) newDateTimeElement(qname, parent, builder);
     } else if (parent instanceof ExtensibleElement || parent instanceof 
Document) {
-      element = (OMElement) newExtensionElement(qname, parent, builder);
+      //element = (OMElement) newExtensionElement(qname, parent, builder);
+      element = (OMElement) new FOMExtensibleElement(qname, parent, 
this,builder);
     }
     return element;
   }
@@ -789,10 +776,6 @@
     return element;
   }
 
-  public void registerExtension(QName qname, Class impl) {
-    extensions.put(qname, impl);
-  }
-  
   public void registerExtension(ExtensionFactory factory) {
     getExtensionFactories().add(factory);
   }
@@ -797,66 +780,6 @@
     getExtensionFactories().add(factory);
   }
 
-  public List<String> getNamespaces() {
-    List<String> namespaces = new ArrayList<String>();
-    for (QName qname : extensions.keySet()) {
-      if (!namespaces.contains(qname.getNamespaceURI()))
-        namespaces.add(qname.getNamespaceURI());
-    }
-    return namespaces;
-  }
-
-  public boolean handlesNamespace(String namespace) {
-    return getNamespaces().contains(namespace);
-  }
-
-  @SuppressWarnings("unchecked")
-  public <T extends Element> T newExtensionElement(
-    QName qname, 
-    Base parent, 
-    Factory factory) {
-      Class _class = extensions.get(qname);
-      if (_class != null) {
-        try {
-          return (T)_class.getConstructor(
-            new Class[] {
-              QName.class,
-              OMContainer.class,
-              OMFactory.class}).newInstance(
-                new Object[] {
-                  qname, 
-                  parent, 
-                  factory});
-        } catch (Exception e) {}
-      }
-      return null;
-  }
-
-  @SuppressWarnings("unchecked")
-  public <T extends Element> T newExtensionElement(
-    QName qname, 
-    Base parent, 
-    Factory factory, 
-    OMXMLParserWrapper parserWrapper) {
-      Class _class = extensions.get(qname);
-      if (_class != null) {
-        try {
-          return (T)_class.getConstructor(
-            new Class[] {
-              QName.class,
-              OMContainer.class,
-              OMFactory.class,
-              OMXMLParserWrapper.class}).newInstance(
-                new Object[] {
-                  qname, 
-                  parent, 
-                  factory,
-                  parserWrapper});
-        } catch (Exception e) {}
-      }
-      return null;
-  }
-
   public Categories newCategories() {
     Document<Categories> doc = newDocument();
     return newCategories(doc);
@@ -876,4 +799,27 @@
   public String newUuidUri() {
     return FOMHelper.generateUuid();
   }
+
+  public void setElementWrapper(Element internal, Element wrapper) {
+    factoriesMap.setElementWrapper(internal, wrapper);
+  }
+  
+  @SuppressWarnings("unchecked")
+  public <T extends Element> T getElementWrapper(Element internal) {
+    String ns = internal.getQName().getNamespaceURI();
+    return (T) ((ATOM_NS.equals(ns) || 
+                 APP_NS.equals(ns) || 
+                 internal.getQName().equals(DIV)) ?
+      internal :
+      factoriesMap.getElementWrapper(internal));
+  }
+
+  public List<String> getNamespaces() {
+    return factoriesMap.getNamespaces();
+  }
+
+  public boolean handlesNamespace(String namespace) {
+    return factoriesMap.handlesNamespace(namespace);
+  }
+
 }
Index: 
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/util/FOMElementIteratorWrapper.java
===================================================================
--- 
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/util/FOMElementIteratorWrapper.java
      (revision 0)
+++ 
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/util/FOMElementIteratorWrapper.java
      (revision 0)
@@ -0,0 +1,47 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.parser.stax.util;
+
+import java.util.Iterator;
+
+import org.apache.abdera.model.Element;
+import org.apache.abdera.parser.stax.FOMFactory;
+
+public class FOMElementIteratorWrapper implements Iterator {
+
+  private final Iterator iterator;
+  private final FOMFactory factory;
+  
+  public FOMElementIteratorWrapper(FOMFactory factory, Iterator iterator) {
+    this.iterator = iterator;
+    this.factory = factory;
+  }
+  
+  public boolean hasNext() {
+    return iterator.hasNext();
+  }
+
+  public Object next() {
+    return factory.getElementWrapper((Element) iterator.next());
+  }
+
+  public void remove() {
+    iterator.remove();
+  }
+
+}
Index: 
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/util/FOMExtensionIterator.java
===================================================================
--- 
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/util/FOMExtensionIterator.java
   (revision 467052)
+++ 
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/util/FOMExtensionIterator.java
   (working copy)
@@ -17,6 +17,8 @@
 */
 package org.apache.abdera.parser.stax.util;
 
+import org.apache.abdera.model.Element;
+import org.apache.abdera.parser.stax.FOMFactory;
 import org.apache.axiom.om.OMElement;
 import org.apache.axiom.om.impl.traverse.OMChildrenIterator;
 
@@ -33,6 +35,7 @@
    */
   private String namespace = null;
   private String extns = null;
+  private FOMFactory factory = null;
 
   /**
    * Field needToMoveForward
@@ -53,6 +56,7 @@
   public FOMExtensionIterator(OMElement parent) {
     super(parent.getFirstOMChild());
     this.namespace = parent.getQName().getNamespaceURI();
+    this.factory = (FOMFactory) parent.getOMFactory();
   }
   
   public FOMExtensionIterator(OMElement parent, String extns) {
@@ -101,7 +105,7 @@
       removeCalled = false;
       lastChild = currentChild;
       currentChild = currentChild.getNextOMSibling();
-      return lastChild;
+      return factory.getElementWrapper((Element)lastChild);
   }
 
   private boolean isQNamesMatch(QName elementQName, String namespace) {
Index: 
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/util/FOMList.java
===================================================================
--- 
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/util/FOMList.java
        (revision 467052)
+++ 
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/util/FOMList.java
        (working copy)
@@ -24,6 +24,8 @@
 import java.util.List;
 import java.util.ListIterator;
 
+import org.apache.abdera.parser.stax.FOMFactory;
+
 /**
  * Implements an ElementSet around an internal buffered iterator.
  * Here's the rationale:
@@ -46,8 +48,8 @@
   extends java.util.AbstractCollection<T>
   implements List<T> {
 
-  private Iterator<T> i = null;
-  private List<T> buffer = new ArrayList<T>();
+  private final Iterator<T> i;
+  private final List<T> buffer = new ArrayList<T>();
   
   public FOMList(Iterator<T> i) {
     this.i = i;

Reply via email to