You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@freemarker.apache.org by dd...@apache.org on 2017/01/20 16:50:49 UTC

[3/5] incubator-freemarker git commit: Removed legacy extensions: rhyno, jython, xml (not to be confused with dom), jdom, ant. Also removed JSP 2.0 support (2.1 is the minimum for now, but maybe it will be 2.2 later).

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/jython/JythonVersionAdapter.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/jython/JythonVersionAdapter.java b/src/main/java/freemarker/ext/jython/JythonVersionAdapter.java
deleted file mode 100644
index 6ec42f4..0000000
--- a/src/main/java/freemarker/ext/jython/JythonVersionAdapter.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  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.
- */
-
-package freemarker.ext.jython;
-
-import org.python.core.PyObject;
-
-/**
- * Functions that has a different implementation depending on the Jython version
- * used. This was introduced to work around class-loading errors because of
- * different classes/methods being present in different Jython versions.
- */
-public abstract class JythonVersionAdapter {
-
-    /**
-     * Returns
-     * <code>obj instanceof Py[Java]Instance</code>. 
-     */
-    public abstract boolean isPyInstance(Object obj);
-    
-    /**
-     * Returns
-     * <code>((PyInstance) py[Java]Instance).__tojava__(java.lang.Object.class)</code>.
-     */
-    public abstract Object pyInstanceToJava(Object pyInstance);
-    
-    /**
-     * Returns <code>pyObject.__class__.__name__</code> 
-     */
-    public abstract String getPythonClassName(PyObject pyObject);
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/jython/JythonVersionAdapterHolder.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/jython/JythonVersionAdapterHolder.java b/src/main/java/freemarker/ext/jython/JythonVersionAdapterHolder.java
deleted file mode 100644
index 013b32c..0000000
--- a/src/main/java/freemarker/ext/jython/JythonVersionAdapterHolder.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  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.
- */
-
-package freemarker.ext.jython;
-
-import org.python.core.PySystemState;
-
-import freemarker.template.utility.StringUtil;
-
-/**
- * Holds the {@link JythonVersionAdapter} so that it's only initialized when this class is accessed.
- * This utilizes that the JVM is required to initialize the fields of a class not earlier than the class is
- * first accessed. Furthermore, it utilizes that the JVM guarantees that the objects created as part of the class
- * initialization will be visible with their after-initialization state for the threads that access it. 
- */
-class JythonVersionAdapterHolder {
-    
-    final static JythonVersionAdapter INSTANCE;
-    static {
-        // Note: Only the textual version number is available in Jython 2.0. 
-        int version;
-        try {
-            // Although PySystemState.version is present in all versions,
-            // its type changes, so we must use reflection to get it.
-            version = StringUtil.versionStringToInt(
-                    PySystemState.class.getField("version").get(null).toString());
-        } catch (Exception e) {
-            throw new RuntimeException("Failed to get Jython version: " + e);
-        }
-        ClassLoader cl = JythonVersionAdapter.class.getClassLoader();
-        try {
-            if (version >= 2005000) {
-                INSTANCE = (JythonVersionAdapter) cl.loadClass(
-                        "freemarker.ext.jython._Jython25VersionAdapter")
-                    .newInstance();
-            } else if (version >= 2002000) {
-                INSTANCE = (JythonVersionAdapter) cl.loadClass(
-                        "freemarker.ext.jython._Jython22VersionAdapter")
-                    .newInstance();
-            } else {
-                INSTANCE = (JythonVersionAdapter) cl.loadClass(
-                        "freemarker.ext.jython._Jython20And21VersionAdapter")
-                    .newInstance();
-            }
-        } catch (ClassNotFoundException e) {
-            throw adapterCreationException(e);
-        } catch (IllegalAccessException e) {
-            throw adapterCreationException(e);
-        } catch (InstantiationException e) {
-            throw adapterCreationException(e);
-        }
-    }
-
-    private static RuntimeException adapterCreationException(Exception e) {
-        return new RuntimeException("Unexpected exception when creating JythonVersionAdapter", e);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/jython/JythonWrapper.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/jython/JythonWrapper.java b/src/main/java/freemarker/ext/jython/JythonWrapper.java
deleted file mode 100644
index eb82818..0000000
--- a/src/main/java/freemarker/ext/jython/JythonWrapper.java
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  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.
- */
-
-package freemarker.ext.jython;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.python.core.Py;
-import org.python.core.PyDictionary;
-import org.python.core.PyFloat;
-import org.python.core.PyInteger;
-import org.python.core.PyLong;
-import org.python.core.PyObject;
-import org.python.core.PySequence;
-import org.python.core.PyString;
-import org.python.core.PyStringMap;
-
-import freemarker.ext.util.ModelCache;
-import freemarker.ext.util.WrapperTemplateModel;
-import freemarker.template.AdapterTemplateModel;
-import freemarker.template.ObjectWrapper;
-import freemarker.template.TemplateBooleanModel;
-import freemarker.template.TemplateHashModel;
-import freemarker.template.TemplateHashModelEx;
-import freemarker.template.TemplateMethodModel;
-import freemarker.template.TemplateMethodModelEx;
-import freemarker.template.TemplateModel;
-import freemarker.template.TemplateModelAdapter;
-import freemarker.template.TemplateModelException;
-import freemarker.template.TemplateNumberModel;
-import freemarker.template.TemplateScalarModel;
-import freemarker.template.TemplateSequenceModel;
-import freemarker.template.utility.OptimizerUtil;
-
-/**
- * An object wrapper that wraps Jython objects into FreeMarker template models
- * and vice versa.
- */
-public class JythonWrapper implements ObjectWrapper {
-    private static final Class PYOBJECT_CLASS = PyObject.class;
-    public static final JythonWrapper INSTANCE = new JythonWrapper();
-
-    private final ModelCache modelCache = new JythonModelCache(this);
-
-    private boolean attributesShadowItems = true;
-
-    public JythonWrapper() {
-    }
-    
-    /**
-     * Sets whether this wrapper caches model instances. Default is false.
-     * When set to true, calling {@link #wrap(Object)} multiple times for
-     * the same object will return the same model.
-     */
-    public void setUseCache(boolean useCache) {
-        modelCache.setUseCache(useCache);
-    }
-    
-    /**
-     * Sets whether attributes shadow items in wrapped objects. When true 
-     * (this is the default value), <code>${object.name}</code> will first 
-     * try to locate a python attribute with the specified name on the object
-     * using {@link PyObject#__findattr__(java.lang.String)}, and only if it 
-     * doesn't find the attribute will it call 
-     * {@link PyObject#__getitem__(org.python.core.PyObject)}.
-     * When set to false, the lookup order is reversed and items
-     * are looked up before attributes.
-     */
-    public synchronized void setAttributesShadowItems(boolean attributesShadowItems) {
-        this.attributesShadowItems = attributesShadowItems;
-    }
-    
-    boolean isAttributesShadowItems() {
-        return attributesShadowItems;
-    }
-    
-    /**
-     * Wraps the passed Jython object into a FreeMarker template model. If
-     * the object is not a Jython object, it's first coerced into one using
-     * {@link Py#java2py(java.lang.Object)}. {@link PyDictionary} and {@link
-     * PyStringMap} are wrapped into a hash model, {@link PySequence}
-     * descendants are wrapped into a sequence model, {@link PyInteger}, {@link
-     * PyLong}, and {@link PyFloat} are wrapped into a number model. All objects
-     * are wrapped into a scalar model (using {@link Object#toString()} and a
-     * boolean model (using {@link PyObject#__nonzero__()}. For internal
-     * general-purpose {@link PyObject}s returned from a call to {@link
-     * #unwrap(TemplateModel)}, the template model that was passed to
-     * <code>unwrap</code> is returned.
-     */
-    public TemplateModel wrap(Object obj) {
-        if (obj == null) {
-            return null;
-        }
-        return modelCache.getInstance(obj);
-    }
-    
-    /**
-     * Coerces a template model into a {@link PyObject}.
-     * @param model the model to coerce
-     * @return the coerced model.
-     * <ul>
-     * <li>
-     * <li>{@link AdapterTemplateModel}s (i.e. {@link freemarker.ext.beans.BeanModel}) are marshalled
-     *   using the standard Python marshaller {@link Py#java2py(Object)} on 
-     *   the result of <code>getWrappedObject(PyObject.class)</code>s. The 
-     *   native JythonModel instances will just return the underlying PyObject. 
-     * <li>All other models that are {@link TemplateScalarModel scalars} are 
-     *   marshalled as {@link PyString}.
-     * <li>All other models that are {@link TemplateNumberModel numbers} are 
-     *   marshalled using the standard Python marshaller
-     *   {@link Py#java2py(Object)} on their underlying <code>Number</code></li>
-     * <li>All other models  are marshalled to a generic internal 
-     *   <code>PyObject</code> subclass that'll correctly pass
-     *   <code>__finditem__</code>, <code>__len__</code>,
-     *   <code>__nonzero__</code>, and <code>__call__</code> invocations to 
-     *   appropriate hash, sequence, and method models.</li>
-     * </ul>
-     */
-    public PyObject unwrap(TemplateModel model) throws TemplateModelException {
-        if (model instanceof AdapterTemplateModel) {
-            return Py.java2py(((AdapterTemplateModel) model).getAdaptedObject(
-                    PYOBJECT_CLASS));
-        }
-        if (model instanceof WrapperTemplateModel) {
-            return Py.java2py(((WrapperTemplateModel) model).getWrappedObject());
-        }
-
-        // Scalars are marshalled to PyString.
-        if (model instanceof TemplateScalarModel) {
-            return new PyString(((TemplateScalarModel) model).getAsString());
-        }
-        
-        // Numbers are wrapped to Python built-in numeric types.
-        if (model instanceof TemplateNumberModel) {
-            Number number = ((TemplateNumberModel) model).getAsNumber();
-            if (number instanceof BigDecimal) {
-                number = OptimizerUtil.optimizeNumberRepresentation(number);
-            }
-            if (number instanceof BigInteger) {
-                // Py.java2py can't automatically coerce a BigInteger into
-                // a PyLong. This will probably get fixed in later Jython
-                // release.
-                return new PyLong((BigInteger) number);
-            } else {
-                return Py.java2py(number);
-            }
-        }
-        // Return generic TemplateModel-to-Python adapter
-        return new TemplateModelToJythonAdapter(model);
-    }
-
-    private class TemplateModelToJythonAdapter extends PyObject 
-    implements TemplateModelAdapter {
-        private final TemplateModel model;
-        
-        TemplateModelToJythonAdapter(TemplateModel model) {
-            this.model = model;
-        }
-        
-        public TemplateModel getTemplateModel() {
-            return model;
-        }
-        
-        @Override
-        public PyObject __finditem__(PyObject key) {
-            if (key instanceof PyInteger) {
-                return __finditem__(((PyInteger) key).getValue());
-            }
-            return __finditem__(key.toString());
-        }
-
-        @Override
-        public PyObject __finditem__(String key) {
-            if (model instanceof TemplateHashModel) {
-                try {
-                    return unwrap(((TemplateHashModel) model).get(key));
-                } catch (TemplateModelException e) {
-                    throw Py.JavaError(e);
-                }
-            }
-            throw Py.TypeError("item lookup on non-hash model (" + getModelClass() + ")");
-        }
-        
-        @Override
-        public PyObject __finditem__(int index) {
-            if (model instanceof TemplateSequenceModel) {
-                try {
-                    return unwrap(((TemplateSequenceModel) model).get(index));
-                } catch (TemplateModelException e) {
-                    throw Py.JavaError(e);
-                }
-            }
-            throw Py.TypeError("item lookup on non-sequence model (" + getModelClass() + ")");
-        }
-        
-        @Override
-        public PyObject __call__(PyObject args[], String keywords[]) {
-            if (model instanceof TemplateMethodModel) {
-                boolean isEx = model instanceof TemplateMethodModelEx;
-                List list = new ArrayList(args.length);
-                try {
-                    for (int i = 0; i < args.length; ++i) {
-                        list.add(
-                            isEx 
-                            ? (Object) wrap(args[i]) 
-                            : (Object) (
-                                args[i] == null 
-                                ? null 
-                                : args[i].toString()));
-                    }
-                    return unwrap((TemplateModel) ((TemplateMethodModelEx) model).exec(list));
-                } catch (TemplateModelException e) {
-                    throw Py.JavaError(e);
-                }
-            }
-            throw Py.TypeError("call of non-method model (" + getModelClass() + ")");
-        }
-        
-        @Override
-        public int __len__() {
-            try {
-                if (model instanceof TemplateSequenceModel) {
-                    return ((TemplateSequenceModel) model).size();
-                }
-                if (model instanceof TemplateHashModelEx) {
-                    return ((TemplateHashModelEx) model).size();
-                }
-            } catch (TemplateModelException e) {
-                throw Py.JavaError(e);
-            }
-            
-            return 0;
-        }
-        
-        @Override
-        public boolean __nonzero__() {
-            try {
-                if (model instanceof TemplateBooleanModel) {
-                    return ((TemplateBooleanModel) model).getAsBoolean();
-                }
-                if (model instanceof TemplateSequenceModel) {
-                    return ((TemplateSequenceModel) model).size() > 0;
-                }
-                if (model instanceof TemplateHashModel) {
-                    return !((TemplateHashModelEx) model).isEmpty();
-                }
-            } catch (TemplateModelException e) {
-                throw Py.JavaError(e);
-            }
-            return false;
-        }
-        
-        private String getModelClass() {
-            return model == null ? "null" : model.getClass().getName();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/jython/_Jython20And21VersionAdapter.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/jython/_Jython20And21VersionAdapter.java b/src/main/java/freemarker/ext/jython/_Jython20And21VersionAdapter.java
deleted file mode 100644
index fe905dd..0000000
--- a/src/main/java/freemarker/ext/jython/_Jython20And21VersionAdapter.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  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.
- */
-
-package freemarker.ext.jython;
-
-import org.python.core.PyJavaInstance;
-import org.python.core.PyObject;
-
-/**
- * Don't use this class; it's only public to work around Google App Engine Java
- * compliance issues. FreeMarker developers only: treat this class as package-visible.
- * 
- * {@link JythonVersionAdapter} for Jython 2.0 and 2.1.
- */
-public class _Jython20And21VersionAdapter extends JythonVersionAdapter {
-
-    public boolean isPyInstance(Object obj) {
-        return obj instanceof PyJavaInstance;
-    }
-
-    public Object pyInstanceToJava(Object pyInstance) {
-        return ((PyJavaInstance) pyInstance).__tojava__(java.lang.Object.class);
-    }
-
-    public String getPythonClassName(PyObject pyObject) {
-        return pyObject.__class__.__name__;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/jython/_Jython22VersionAdapter.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/jython/_Jython22VersionAdapter.java b/src/main/java/freemarker/ext/jython/_Jython22VersionAdapter.java
deleted file mode 100644
index 30173df..0000000
--- a/src/main/java/freemarker/ext/jython/_Jython22VersionAdapter.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  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.
- */
-
-package freemarker.ext.jython;
-
-import org.python.core.PyJavaInstance;
-import org.python.core.PyObject;
-
-/**
- * Don't use this class; it's only public to work around Google App Engine Java
- * compliance issues. FreeMarker developers only: treat this class as package-visible.
- * 
- * {@link JythonVersionAdapter} for Jython 2.2.
- */
-public class _Jython22VersionAdapter extends JythonVersionAdapter {
-
-    public boolean isPyInstance(Object obj) {
-        return obj instanceof PyJavaInstance;
-    }
-
-    public Object pyInstanceToJava(Object pyInstance) {
-        return ((PyJavaInstance) pyInstance).__tojava__(java.lang.Object.class);
-    }
-
-    public String getPythonClassName(PyObject pyObject) {
-        return pyObject.getType().getFullName();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/jython/_Jython25VersionAdapter.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/jython/_Jython25VersionAdapter.java b/src/main/java/freemarker/ext/jython/_Jython25VersionAdapter.java
deleted file mode 100644
index 27d58a8..0000000
--- a/src/main/java/freemarker/ext/jython/_Jython25VersionAdapter.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  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.
- */
-
-package freemarker.ext.jython;
-
-import org.python.core.PyInstance;
-import org.python.core.PyObject;
-
-/**
- * Don't use this class; it's only public to work around Google App Engine Java
- * compliance issues. FreeMarker developers only: treat this class as package-visible.
- * 
- * {@link JythonVersionAdapter} for Jython 2.5.
- */
-public class _Jython25VersionAdapter extends JythonVersionAdapter {
-
-    @Override
-    public boolean isPyInstance(Object obj) {
-        return obj instanceof PyInstance;
-    }
-
-    @Override
-    public Object pyInstanceToJava(Object pyInstance) {
-        return ((PyInstance) pyInstance).__tojava__(java.lang.Object.class);
-    }
-
-    @Override
-    public String getPythonClassName(PyObject pyObject) {
-        return pyObject.getType().getName();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/jython/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/jython/package.html b/src/main/java/freemarker/ext/jython/package.html
deleted file mode 100644
index b979552..0000000
--- a/src/main/java/freemarker/ext/jython/package.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  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.
--->
-<html>
-<head>
-<title></title>
-</head>
-<body>
-
-<p>Exposes <a href="http://www.jython.org" target="_blank">Jython</a> objects to templates.
-The {@link freemarker.template.DefaultObjectWrapper default object wrapper} of FreeMarker
-automatically wraps Jython nodes with this.
-
-<p>Most of the issues dealing with Jython objects are handled by the 
-{@link freemarker.ext.jython.JythonWrapper#wrap(Object)} method. In 
-normal cases, this is the only method you should use to turn an 
-arbitrary Jython object into a FreeMarker 
-{@link freemarker.template.TemplateModel}. Additionally, you can 
-manually create instances of any wrapper class using its constructors.
-
-</body>
-</html>

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/rhino/RhinoFunctionModel.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/rhino/RhinoFunctionModel.java b/src/main/java/freemarker/ext/rhino/RhinoFunctionModel.java
deleted file mode 100644
index 61674a1..0000000
--- a/src/main/java/freemarker/ext/rhino/RhinoFunctionModel.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  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.
- */
-
-package freemarker.ext.rhino;
-
-import java.util.List;
-
-import org.mozilla.javascript.Context;
-import org.mozilla.javascript.Function;
-import org.mozilla.javascript.Scriptable;
-import org.mozilla.javascript.ScriptableObject;
-
-import freemarker.ext.beans.BeansWrapper;
-import freemarker.template.TemplateMethodModelEx;
-import freemarker.template.TemplateModel;
-import freemarker.template.TemplateModelException;
-
-/**
- */
-public class RhinoFunctionModel extends RhinoScriptableModel 
-implements TemplateMethodModelEx {
-
-    private final Scriptable fnThis;
-    
-    public RhinoFunctionModel(Function function, Scriptable fnThis, 
-            BeansWrapper wrapper) {
-        super(function, wrapper);
-        this.fnThis = fnThis;
-    }
-    
-    public Object exec(List arguments) throws TemplateModelException {
-        Context cx = Context.getCurrentContext();
-        Object[] args = arguments.toArray();
-        BeansWrapper wrapper = getWrapper();
-        for (int i = 0; i < args.length; i++) {
-            args[i] = wrapper.unwrap((TemplateModel) args[i]);
-        }
-        return wrapper.wrap(((Function) getScriptable()).call(cx, 
-                ScriptableObject.getTopLevelScope(fnThis), fnThis, args));
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/rhino/RhinoScriptableModel.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/rhino/RhinoScriptableModel.java b/src/main/java/freemarker/ext/rhino/RhinoScriptableModel.java
deleted file mode 100644
index a39ae70..0000000
--- a/src/main/java/freemarker/ext/rhino/RhinoScriptableModel.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  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.
- */
-
-package freemarker.ext.rhino;
-
-import org.mozilla.javascript.Context;
-import org.mozilla.javascript.EvaluatorException;
-import org.mozilla.javascript.Function;
-import org.mozilla.javascript.NativeJavaObject;
-import org.mozilla.javascript.Scriptable;
-import org.mozilla.javascript.ScriptableObject;
-
-import freemarker.ext.beans.BeansWrapper;
-import freemarker.ext.util.ModelFactory;
-import freemarker.template.AdapterTemplateModel;
-import freemarker.template.ObjectWrapper;
-import freemarker.template.TemplateBooleanModel;
-import freemarker.template.TemplateCollectionModel;
-import freemarker.template.TemplateHashModelEx;
-import freemarker.template.TemplateModel;
-import freemarker.template.TemplateModelException;
-import freemarker.template.TemplateNumberModel;
-import freemarker.template.TemplateScalarModel;
-import freemarker.template.TemplateSequenceModel;
-
-/**
- */
-public class RhinoScriptableModel implements TemplateHashModelEx, 
-TemplateSequenceModel, AdapterTemplateModel, TemplateScalarModel, 
-TemplateBooleanModel, TemplateNumberModel {
-    static final ModelFactory FACTORY = new ModelFactory() {
-        public TemplateModel create(Object object, ObjectWrapper wrapper) {
-            return new RhinoScriptableModel((Scriptable) object, 
-                    (BeansWrapper) wrapper);
-        }
-    };
-    
-    private final Scriptable scriptable;
-    private final BeansWrapper wrapper;
-    
-    public RhinoScriptableModel(Scriptable scriptable, BeansWrapper wrapper) {
-        this.scriptable = scriptable;
-        this.wrapper = wrapper;
-    }
-    
-    public TemplateModel get(String key) throws TemplateModelException {
-        Object retval = ScriptableObject.getProperty(scriptable, key);
-        if (retval instanceof Function) {
-            return new RhinoFunctionModel((Function) retval, scriptable, wrapper);
-        } else {
-            return wrapper.wrap(retval);
-        }
-    }
-    
-    public TemplateModel get(int index) throws TemplateModelException {
-        Object retval = ScriptableObject.getProperty(scriptable, index);
-        if (retval instanceof Function) {
-            return new RhinoFunctionModel((Function) retval, scriptable, wrapper);
-        } else {
-            return wrapper.wrap(retval);
-        }
-    }
-    
-    public boolean isEmpty() {
-        return scriptable.getIds().length == 0;
-    }
-    
-    public TemplateCollectionModel keys() throws TemplateModelException {
-        return (TemplateCollectionModel) wrapper.wrap(scriptable.getIds());
-    }
-    
-    public int size() {
-        return scriptable.getIds().length;
-    }
-    
-    public TemplateCollectionModel values() throws TemplateModelException {
-        Object[] ids = scriptable.getIds();
-        Object[] values = new Object[ids.length];
-        for (int i = 0; i < values.length; i++) {
-            Object id = ids[i];
-            if (id instanceof Number) {
-                values[i] = ScriptableObject.getProperty(scriptable, 
-                        ((Number) id).intValue());
-            } else {
-                values[i] = ScriptableObject.getProperty(scriptable, 
-                        String.valueOf(id)); 
-            }
-        }
-        return (TemplateCollectionModel) wrapper.wrap(values);
-    }
-    
-    public boolean getAsBoolean() {
-        return Context.toBoolean(scriptable);
-    }
-    
-    public Number getAsNumber() {
-        return Double.valueOf(Context.toNumber(scriptable));
-    }
-    
-    public String getAsString() {
-        return Context.toString(scriptable);
-    }
-    
-    Scriptable getScriptable() {
-        return scriptable;
-    }
-
-    BeansWrapper getWrapper() {
-        return wrapper;
-    }
-
-    public Object getAdaptedObject(Class hint) {
-        // FIXME: This does LS3 conversion, which is not very useful for us. Like it won't convert to List, Map, etc.  
-        try {
-            return NativeJavaObject.coerceType(hint, scriptable);
-        } catch (EvaluatorException e) {
-            return NativeJavaObject.coerceType(Object.class, scriptable);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/rhino/RhinoWrapper.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/rhino/RhinoWrapper.java b/src/main/java/freemarker/ext/rhino/RhinoWrapper.java
deleted file mode 100644
index 9b06bac..0000000
--- a/src/main/java/freemarker/ext/rhino/RhinoWrapper.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  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.
- */
-
-package freemarker.ext.rhino;
-
-import java.security.AccessController;
-import java.security.PrivilegedExceptionAction;
-
-import org.mozilla.javascript.Scriptable;
-import org.mozilla.javascript.Undefined;
-import org.mozilla.javascript.UniqueTag;
-import org.mozilla.javascript.Wrapper;
-
-import freemarker.ext.beans.BeansWrapper;
-import freemarker.ext.util.ModelFactory;
-import freemarker.template.TemplateModel;
-import freemarker.template.TemplateModelException;
-import freemarker.template.utility.UndeclaredThrowableException;
-
-/**
- */
-public class RhinoWrapper extends BeansWrapper {
-    // The type of the "instance" field changed between Rhino versions, so a
-    // GETSTATIC with wrong type declaration would cause a NoSuchFieldError;
-    // we're avoiding it by acquiring it reflectively.
-    private static final Object UNDEFINED_INSTANCE;
-    static {
-        try {
-            UNDEFINED_INSTANCE = AccessController.doPrivileged(new PrivilegedExceptionAction() {
-                public Object run() throws Exception {
-                    return Undefined.class.getField("instance").get(null);
-                }
-            });
-        } catch (RuntimeException e) {
-            throw e;
-        } catch (Exception e) {
-            throw new UndeclaredThrowableException(e);
-        }
-    }
-    
-    @Override
-    public TemplateModel wrap(Object obj) throws TemplateModelException {
-        // So our existence builtins work as expected.
-        if (obj == UNDEFINED_INSTANCE || obj == UniqueTag.NOT_FOUND) {
-            return null;
-        }
-        // UniqueTag.NULL_VALUE represents intentionally set null in Rhino, and
-        // BeansWrapper#nullModel also represents intentionally returned null.
-        // I [A.Sz.] am fairly certain that this value is never passed out of
-        // any of the Rhino code back to clients, but is instead always being
-        // converted back to null. However, since this object is available to 
-        // any 3rd party Scriptable implementations as well, they might return
-        // it, so we'll just be on the safe side, and handle it.
-        if (obj == UniqueTag.NULL_VALUE) {
-            return super.wrap(null);
-        }
-        // So, say, a JavaAdapter for FreeMarker interfaces works
-        if (obj instanceof Wrapper) {
-            obj = ((Wrapper) obj).unwrap();
-        }
-        return super.wrap(obj);
-    }
-
-    @Override
-    protected ModelFactory getModelFactory(Class clazz) {
-        if (Scriptable.class.isAssignableFrom(clazz)) {
-            return RhinoScriptableModel.FACTORY;
-        }
-        return super.getModelFactory(clazz);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/rhino/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/rhino/package.html b/src/main/java/freemarker/ext/rhino/package.html
deleted file mode 100644
index ede49a8..0000000
--- a/src/main/java/freemarker/ext/rhino/package.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  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.
--->
-<html>
-<head>
-<title></title>
-</head>
-<body>
-
-<p>Exposes Rhino (ECMAScript) objects to templates.
-
-</body>
-</html>

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/servlet/FreemarkerServlet.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/servlet/FreemarkerServlet.java b/src/main/java/freemarker/ext/servlet/FreemarkerServlet.java
index 4bc7504..504bbeb 100644
--- a/src/main/java/freemarker/ext/servlet/FreemarkerServlet.java
+++ b/src/main/java/freemarker/ext/servlet/FreemarkerServlet.java
@@ -403,7 +403,6 @@ public class FreemarkerServlet extends HttpServlet {
     private static final String DEPR_INITPARAM_OBJECT_WRAPPER = "ObjectWrapper";
     private static final String DEPR_INITPARAM_WRAPPER_SIMPLE = "simple";
     private static final String DEPR_INITPARAM_WRAPPER_BEANS = "beans";
-    private static final String DEPR_INITPARAM_WRAPPER_JYTHON = "jython";
     private static final String DEPR_INITPARAM_TEMPLATE_EXCEPTION_HANDLER = "TemplateExceptionHandler";
     private static final String DEPR_INITPARAM_TEMPLATE_EXCEPTION_HANDLER_RETHROW = "rethrow";
     private static final String DEPR_INITPARAM_TEMPLATE_EXCEPTION_HANDLER_DEBUG = "debug";
@@ -1293,19 +1292,6 @@ public class FreemarkerServlet extends HttpServlet {
             if (DEPR_INITPARAM_WRAPPER_SIMPLE.equals(wrapper)) {
                 return ObjectWrapper.SIMPLE_WRAPPER;
             }
-            if (DEPR_INITPARAM_WRAPPER_JYTHON.equals(wrapper)) {
-                // Avoiding compile-time dependency on Jython package
-                try {
-                    return (ObjectWrapper) Class.forName("freemarker.ext.jython.JythonWrapper")
-                            .newInstance();
-                } catch (InstantiationException e) {
-                    throw new InstantiationError(e.getMessage());
-                } catch (IllegalAccessException e) {
-                    throw new IllegalAccessError(e.getMessage());
-                } catch (ClassNotFoundException e) {
-                    throw new NoClassDefFoundError(e.getMessage());
-                }
-            }
             return createDefaultObjectWrapper();
         } else {
             wrapper = getInitParameter(Configurable.OBJECT_WRAPPER_KEY);

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/xml/Namespaces.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/xml/Namespaces.java b/src/main/java/freemarker/ext/xml/Namespaces.java
deleted file mode 100644
index 8c4ce75..0000000
--- a/src/main/java/freemarker/ext/xml/Namespaces.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  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.
- */
-
-package freemarker.ext.xml;
-import java.util.HashMap;
-import java.util.List;
-
-import freemarker.template.TemplateMethodModel;
-import freemarker.template.TemplateModelException;
-import freemarker.template.TemplateScalarModel;
-
-/**
- */
-class Namespaces
-implements
-    TemplateMethodModel,
-    Cloneable {
-    private HashMap namespaces;
-    private boolean shared;
-        
-    Namespaces() {
-        namespaces = new HashMap();
-        namespaces.put("", "");
-        namespaces.put("xml", "http://www.w3.org/XML/1998/namespace");
-        shared = false;
-    }
-        
-    @Override
-    public Object clone() {
-        try {
-            Namespaces clone = (Namespaces) super.clone();
-            clone.namespaces = (HashMap) namespaces.clone();
-            clone.shared = false;
-            return clone;
-        } catch (CloneNotSupportedException e) {
-            throw new Error(); // Cannot happen
-        }
-    }
-    
-    public String translateNamespacePrefixToUri(String prefix) {
-        synchronized (namespaces) {
-            return (String) namespaces.get(prefix);
-        }   
-    }
-    
-    public Object exec(List arguments) throws TemplateModelException {
-        if (arguments.size() != 2) {
-            throw new TemplateModelException("_registerNamespace(prefix, uri) requires two arguments");
-        }
-        registerNamespace((String) arguments.get(0), (String) arguments.get(1));
-        return TemplateScalarModel.EMPTY_STRING;
-    }
-    
-    void registerNamespace(String prefix, String uri) {
-        synchronized (namespaces) {
-            namespaces.put(prefix, uri);
-        }   
-    }
-    
-    void markShared() {
-        if (!shared) {
-            shared = true;
-        }
-    }
-    
-    boolean isShared() {
-        return shared;
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/xml/Navigator.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/xml/Navigator.java b/src/main/java/freemarker/ext/xml/Navigator.java
deleted file mode 100644
index 2a2542f..0000000
--- a/src/main/java/freemarker/ext/xml/Navigator.java
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  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.
- */
-
-package freemarker.ext.xml;
-
-import java.io.StringWriter;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.WeakHashMap;
-
-import org.jaxen.NamespaceContext;
-
-import freemarker.template.TemplateModelException;
-
-/**
- */
-abstract class Navigator {
-    // Cache of already parsed XPath expressions
-    private final Map xpathCache = new WeakHashMap();
-    // Operators this navigator defines
-    private final Map operators = createOperatorMap();
-    private final NodeOperator attributeOperator = getOperator("_attributes");
-    private final NodeOperator childrenOperator = getOperator("_children");
-    
-    NodeOperator getOperator(String key) {
-        return (NodeOperator) operators.get(key);
-    }
-    
-    NodeOperator getAttributeOperator() {
-        return attributeOperator;
-    }
-    
-    NodeOperator getChildrenOperator() {
-        return childrenOperator;
-    }
-    
-    abstract void getAsString(Object node, StringWriter sw)
-    throws TemplateModelException;
-
-    List applyXPath(List nodes, String xpathString, Object namespaces)
-    throws TemplateModelException {
-        XPathEx xpath = null;
-        try {
-            synchronized (xpathCache) {
-                xpath = (XPathEx) xpathCache.get(xpathString);
-                if (xpath == null) {
-                    xpath = createXPathEx(xpathString);
-                    xpathCache.put(xpathString, xpath);
-                }
-            }
-            return xpath.selectNodes(nodes, (NamespaceContext) namespaces);
-        } catch (Exception e) {
-            throw new TemplateModelException("Could not evaulate XPath expression " + xpathString, e);
-        }
-    }
-    
-    interface XPathEx {
-        List selectNodes(Object nodes, NamespaceContext namespaces)  throws TemplateModelException;
-    }
-    
-    abstract XPathEx createXPathEx(String xpathString) throws TemplateModelException;
-
-    abstract void getChildren(Object node, String localName, String namespaceUri, List result);
-    
-    abstract void getAttributes(Object node, String localName, String namespaceUri, List result);
-
-    abstract void getDescendants(Object node, List result);
-
-    abstract Object getParent(Object node);
-    
-    abstract Object getDocument(Object node);
-    
-    abstract Object getDocumentType(Object node);
-
-    private void getAncestors(Object node, List result) {
-        for (; ; ) {
-            Object parent = getParent(node);
-            if (parent == null) {
-                break;
-            }
-            result.add(parent);
-            node = parent;
-        }
-    }
-    
-    abstract void getContent(Object node, List result);
-
-    abstract String getText(Object node);
-
-    abstract String getLocalName(Object node);
-
-    abstract String getNamespacePrefix(Object node);
-
-    String getQualifiedName(Object node) {
-        String lname = getLocalName(node);
-        if (lname == null) {
-            return null;
-        }
-        String nsprefix = getNamespacePrefix(node);
-        if (nsprefix == null || nsprefix.length() == 0) {
-            return lname;
-        } else {
-            return nsprefix + ":" + lname;
-        }
-    }
-    
-    abstract String getType(Object node);
-
-    abstract String getNamespaceUri(Object node);
-
-    boolean equal(String s1, String s2) {
-        return s1 == null ? s2 == null : s1.equals(s2);
-    }
-    
-    private Map createOperatorMap() {
-        Map map = new HashMap();
-        map.put("_attributes", new AttributesOp());
-        map.put("@*", map.get("_attributes"));
-        map.put("_children", new ChildrenOp());
-        map.put("*", map.get("_children"));
-        map.put("_descendantOrSelf", new DescendantOrSelfOp());
-        map.put("_descendant", new DescendantOp());
-        map.put("_document", new DocumentOp());
-        map.put("_doctype", new DocumentTypeOp());
-        map.put("_ancestor", new AncestorOp());
-        map.put("_ancestorOrSelf", new AncestorOrSelfOp());
-        map.put("_content", new ContentOp());
-        map.put("_name", new LocalNameOp());
-        map.put("_nsprefix", new NamespacePrefixOp());
-        map.put("_nsuri", new NamespaceUriOp());
-        map.put("_parent", new ParentOp());
-        map.put("_qname", new QualifiedNameOp());
-        map.put("_text", new TextOp());
-        map.put("_type", new TypeOp());
-        return map;
-    }
-
-    private class ChildrenOp implements NodeOperator {
-        public void process(Object node, String localName, String namespaceUri, List result) {
-            getChildren(node, localName, namespaceUri, result);
-        }
-    }
-
-    private class AttributesOp implements NodeOperator {
-        public void process(Object node, String localName, String namespaceUri, List result) {
-            getAttributes(node, localName, namespaceUri, result);
-        }
-    }
-
-    private class DescendantOrSelfOp implements NodeOperator {
-        public void process(Object node, String localName, String namespaceUri, List result) {
-            result.add(node);
-            getDescendants(node, result);
-        }
-    }
-
-    private class DescendantOp implements NodeOperator {
-        public void process(Object node, String localName, String namespaceUri, List result) {
-            getDescendants(node, result);
-        }
-    }
-
-    private class AncestorOrSelfOp implements NodeOperator {
-        public void process(Object node, String localName, String namespaceUri, List result) {
-            result.add(node);
-            getAncestors(node, result);
-        }
-    }
-
-    private class AncestorOp implements NodeOperator {
-        public void process(Object node, String localName, String namespaceUri, List result) {
-            getAncestors(node, result);
-        }
-    }
-
-    private class ParentOp implements NodeOperator {
-        public void process(Object node, String localName, String namespaceUri, List result) {
-            Object parent = getParent(node);
-            if (parent != null) {
-                result.add(parent);
-            }
-        }
-    }
-
-    private class DocumentOp implements NodeOperator {
-        public void process(Object node, String localName, String namespaceUri, List result) {
-            Object document = getDocument(node);
-            if (document != null) {
-                result.add(document);
-            }
-        }
-    }
-
-    private class DocumentTypeOp implements NodeOperator {
-        public void process(Object node, String localName, String namespaceUri, List result) {
-            Object documentType = getDocumentType(node);
-            if (documentType != null) {
-                result.add(documentType);
-            }
-        }
-    }
-
-    private class ContentOp implements NodeOperator {
-        public void process(Object node, String localName, String namespaceUri, List result) {
-            getContent(node, result);
-        }
-    }
-
-    private class TextOp implements NodeOperator {
-        public void process(Object node, String localName, String namespaceUri, List result) {
-            String text = getText(node);
-            if (text != null) {
-                result.add(text);
-            }
-        }
-    }
-
-    private class LocalNameOp implements NodeOperator {
-        public void process(Object node, String localName, String namespaceUri, List result) {
-            String text = getLocalName(node);
-            if (text != null) {
-                result.add(text);
-            }
-        }
-    }
-
-    private class QualifiedNameOp implements NodeOperator {
-        public void process(Object node, String localName, String namespaceUri, List result) {
-            String qname = getQualifiedName(node);
-            if (qname != null) {
-                result.add(qname);
-            }
-        }
-    }
-
-    private class NamespacePrefixOp implements NodeOperator {
-        public void process(Object node, String localName, String namespaceUri, List result) {
-            String text = getNamespacePrefix(node);
-            if (text != null) {
-                result.add(text);
-            }
-        }
-    }
-
-    private class NamespaceUriOp implements NodeOperator {
-        public void process(Object node, String localName, String namespaceUri, List result) {
-            String text = getNamespaceUri(node);
-            if (text != null) {
-                result.add(text);
-            }
-        }
-    }
-
-    private class TypeOp implements NodeOperator {
-        public void process(Object node, String localName, String namespaceUri, List result) {
-            result.add(getType(node));
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/xml/NodeListModel.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/xml/NodeListModel.java b/src/main/java/freemarker/ext/xml/NodeListModel.java
deleted file mode 100644
index d42643d..0000000
--- a/src/main/java/freemarker/ext/xml/NodeListModel.java
+++ /dev/null
@@ -1,554 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  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.
- */
-
-package freemarker.ext.xml;
-
-import java.io.StringWriter;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-import freemarker.log.Logger;
-import freemarker.template.TemplateHashModel;
-import freemarker.template.TemplateMethodModel;
-import freemarker.template.TemplateModel;
-import freemarker.template.TemplateModelException;
-import freemarker.template.TemplateNodeModel;
-import freemarker.template.TemplateScalarModel;
-import freemarker.template.TemplateSequenceModel;
-import freemarker.template.utility.ClassUtil;
-
-/**
- * <p>A data model adapter for three widespread XML document object model
- * representations: W3C DOM, dom4j, and JDOM. The adapter automatically
- * recognizes the used XML object model and provides a unified interface for it
- * toward the template. The model provides access to all XML InfoSet features
- * of the XML document and includes XPath support if it has access to the XPath-
- * evaluator library Jaxen. The model's philosophy (which closely follows that
- * of XML InfoSet and XPath) is as follows: it always wraps a list of XML nodes
- * (the "nodelist"). The list can be empty, can have a single element, or can
- * have multiple elements. Every operation applied to the model is applied to
- * all nodes in its nodelist. You usually start with a single- element nodelist,
- * usually the root element node or the document node of the XML tree.
- * Additionally, the nodes can contain String objects as a result of certain
- * evaluations (getting the names of elements, values of attributes, etc.)</p>
- * <p><strong>Implementation note:</strong> If you are using W3C DOM documents
- * built by the Crimson XML parser (or you are using the built-in JDK 1.4 XML
- * parser, which is essentially Crimson), make sure you call
- * <tt>setNamespaceAware(true)</tt> on the 
- * <tt>javax.xml.parsers.DocumentBuilderFactory</tt> instance used for document
- * building even when your documents don't use XML namespaces. Failing to do so,
- * you will experience incorrect behavior when using the documents wrapped with
- * this model.</p>
- *
- * @deprecated Use {@link freemarker.ext.dom.NodeModel} instead.
- */
-@Deprecated
-public class NodeListModel
-implements
-    TemplateHashModel,
-    TemplateMethodModel,
-    TemplateScalarModel,
-    TemplateSequenceModel,
-    TemplateNodeModel {
-    private static final Logger LOG = Logger.getLogger("freemarker.xml");
-    
-    private static final Class DOM_NODE_CLASS = getClass("org.w3c.dom.Node");
-    private static final Class DOM4J_NODE_CLASS = getClass("org.dom4j.Node");
-    private static final Navigator DOM_NAVIGATOR = getNavigator("Dom");
-    private static final Navigator DOM4J_NAVIGATOR = getNavigator("Dom4j");
-    private static final Navigator JDOM_NAVIGATOR = getNavigator("Jdom");
-    private static volatile boolean useJaxenNamespaces = true;
-    
-    // The navigator object that implements document model-specific behavior.
-    private final Navigator navigator;
-    // The contained nodes
-    private final List nodes;
-    // The namespaces object (potentially shared by multiple models)
-    private Namespaces namespaces;
-
-    /**
-     * Creates a new NodeListModel, wrapping the passed nodes.
-     * @param nodes you can pass it a single XML node from any supported
-     * document model, or a Java collection containing any number of nodes.
-     * Passing null is prohibited. To create an empty model, pass it an empty
-     * collection. If a collection is passed, all passed nodes must belong to
-     * the same XML object model, i.e. you can't mix JDOM and dom4j in a single
-     * instance of NodeListModel. The model itself doesn't check for this condition,
-     * as it can be time consuming, but will throw spurious
-     * {@link ClassCastException}s when it encounters mixed objects.
-     * @throws IllegalArgumentException if you pass null
-     */
-    public NodeListModel(Object nodes) {
-        Object node = nodes;
-        if (nodes instanceof Collection) {
-            this.nodes = new ArrayList((Collection) nodes);
-            node = this.nodes.isEmpty() ? null : this.nodes.get(0);
-        } else if (nodes != null) {
-            this.nodes = Collections.singletonList(nodes);
-        } else {
-            throw new IllegalArgumentException("nodes == null");
-        }
-        if (DOM_NODE_CLASS != null && DOM_NODE_CLASS.isInstance(node)) {
-            navigator = DOM_NAVIGATOR;
-        } else if (DOM4J_NODE_CLASS != null && DOM4J_NODE_CLASS.isInstance(node)) {
-            navigator = DOM4J_NAVIGATOR;
-        } else {
-            // Assume JDOM
-            navigator = JDOM_NAVIGATOR;
-        }
-        namespaces = createNamespaces();
-    }
-    
-    private Namespaces createNamespaces() {
-        if (useJaxenNamespaces) {
-            try {
-            	return (Namespaces)
-            			Class.forName("freemarker.ext.xml._JaxenNamespaces")
-            			.newInstance();
-            } catch (Throwable t) {
-                useJaxenNamespaces = false;
-            }
-        }
-        return new Namespaces();
-    }
-
-    private NodeListModel(Navigator navigator, List nodes, Namespaces namespaces) {
-        this.navigator = navigator;
-        this.nodes = nodes;
-        this.namespaces = namespaces;
-    }
-
-    private NodeListModel deriveModel(List derivedNodes) {
-        namespaces.markShared();
-        return new NodeListModel(navigator, derivedNodes, namespaces);
-    }
-    
-    /**
-     * Returns the number of nodes in this model's nodelist.
-     * @see freemarker.template.TemplateSequenceModel#size()
-     */
-    public int size() {
-        return nodes.size();
-    }
-
-    /**
-     * Evaluates an XPath expression on XML nodes in this model.
-     * @param arguments the arguments to the method invocation. Expectes exactly
-     * one argument - the XPath expression.
-     * @return a new NodeListModel with nodes selected by applying the XPath
-     * expression to this model's nodelist.
-     * @see freemarker.template.TemplateMethodModel#exec(List)
-     */
-    public Object exec(List arguments) throws TemplateModelException {
-        if (arguments.size() != 1) {
-            throw new TemplateModelException(
-                "Expecting exactly one argument - an XPath expression");
-        }
-        return deriveModel(navigator.applyXPath(nodes, (String) arguments.get(0), namespaces));
-    }
-
-    /**
-     * Returns the string representation of the wrapped nodes. String objects in
-     * the nodelist are rendered as-is (with no XML escaping applied). All other
-     * nodes are rendered in the default XML serialization format ("plain XML").
-     * This makes the model quite suited for use as an XML-transformation tool.
-     * @return the string representation of the wrapped nodes. String objects
-     * in the nodelist are rendered as-is (with no XML escaping applied). All
-     * other nodes are rendered in the default XML serialization format ("plain
-     * XML"). 
-     * @see freemarker.template.TemplateScalarModel#getAsString()
-     */
-    public String getAsString() throws TemplateModelException {
-        StringWriter sw = new StringWriter(size() * 128);
-        for (Iterator iter = nodes.iterator(); iter.hasNext(); ) {
-            Object o = iter.next();
-            if (o instanceof String) {
-                sw.write((String) o);
-            } else {
-                navigator.getAsString(o, sw);
-           }
-        }
-        return sw.toString();
-    }
-
-    /**
-     * Selects a single node from this model's nodelist by its list index and
-     * returns a new NodeListModel containing that single node.
-     * @param index the ordinal number of the selected node 
-     * @see freemarker.template.TemplateSequenceModel#get(int)
-     */
-    public TemplateModel get(int index) {
-        return deriveModel(Collections.singletonList(nodes.get(index)));
-    }
-
-    /**
-     * Returns a new NodeListModel containing the nodes that result from applying
-     * an operator to this model's nodes.
-     * @param key the operator to apply to nodes. Available operators are:
-     * <table style="width: auto; border-collapse: collapse" border="1" summary="XML node hash keys">
-     *   <thead>
-     *     <tr>
-     *       <th align="left">Key name</th>
-     *       <th align="left">Evaluates to</th>
-     *     </tr>  
-     *   </thead>
-     *   <tbody>
-     *     <tr>
-     *       <td><tt>*</tt> or <tt>_children</tt></td>
-     *       <td>all direct element children of current nodes (non-recursive).
-     *         Applicable to element and document nodes.</td>
-     *     </tr>  
-     *     <tr>
-     *       <td><tt>@*</tt> or <tt>_attributes</tt></td>
-     *       <td>all attributes of current nodes. Applicable to elements only.
-     *         </td>
-     *     </tr>
-     *     <tr>
-     *       <td><tt>@<i>attributeName</i></tt></td>
-     *       <td>named attributes of current nodes. Applicable to elements, 
-     *         doctypes and processing instructions. On doctypes it supports 
-     *         attributes <tt>publicId</tt>, <tt>systemId</tt> and 
-     *         <tt>elementName</tt>. On processing instructions, it supports 
-     *         attributes <tt>target</tt> and <tt>data</tt>, as well as any 
-     *         other attribute name specified in data as 
-     *         <tt>name=&quot;value&quot;</tt> pair on dom4j or JDOM models. 
-     *         The attribute nodes for doctype and processing instruction are 
-     *         synthetic, and as such have no parent. Note, however that 
-     *         <tt>@*</tt> does NOT operate on doctypes or processing 
-     *         instructions.</td>
-     *     </tr>  
-     * 
-     *     <tr>
-     *       <td><tt>_ancestor</tt></td>
-     *       <td>all ancestors up to root element (recursive) of current nodes.
-     *         Applicable to same node types as <tt>_parent</tt>.</td>
-     *     </tr>  
-     *     <tr>
-     *       <td><tt>_ancestorOrSelf</tt></td>
-     *       <td>all ancestors of current nodes plus current nodes. Applicable 
-     *         to same node types as <tt>_parent</tt>.</td>
-     *     </tr>  
-     *     <tr>
-     *       <td><tt>_cname</tt></td>
-     *       <td>the canonical names of current nodes (namespace URI + local 
-     *         name), one string per node (non-recursive). Applicable to 
-     *         elements and attributes</td>
-     *     </tr>  
-     *     <tr>
-     *       <td><tt>_content</tt></td>
-     *       <td>the complete content of current nodes, including children 
-     *         elements, text, entity references, and processing instructions 
-     *         (non-recursive). Applicable to elements and documents.</td>
-     *     </tr>  
-     *     <tr>
-     *       <td><tt>_descendant</tt></td>
-     *       <td>all recursive descendant element children of current nodes. 
-     *         Applicable to document and element nodes.</td>
-     *     </tr>  
-     *     <tr>
-     *       <td><tt>_descendantOrSelf</tt></td>
-     *       <td>all recursive descendant element children of current nodes 
-     *         plus current nodes. Applicable to document and element nodes.
-     *         </td>
-     *     </tr>
-     *     <tr>
-     *       <td><tt>_document</tt></td>
-     *       <td>all documents the current nodes belong to. Applicable to all 
-     *       nodes except text.</td>
-     *     </tr>
-     *     <tr>
-     *       <td><tt>_doctype</tt></td>
-     *       <td>doctypes of the current nodes. Applicable to document nodes 
-     *       only.</td>
-     *     </tr>
-     *     <tr>
-     *       <td><tt>_filterType</tt></td>
-     *       <td>is a filter-by-type template method model. When called, it 
-     *         will yield a node list that contains only those current nodes 
-     *         whose type matches one of types passed as argument. You can pass
-     *         as many string arguments as you want, each representing one of
-     *         the types to select: &quot;attribute&quot;, &quot;cdata&quot;,
-     *         &quot;comment&quot;, &quot;document&quot;, 
-     *         &quot;documentType&quot;, &quot;element&quot;, 
-     *         &quot;entity&quot;, &quot;entityReference&quot;,
-     *         &quot;namespace&quot;, &quot;processingInstruction&quot;, or
-     *         &quot;text&quot;.</td>
-     *     </tr>
-     *     <tr>
-     *       <td><tt>_name</tt></td>
-     *       <td>the names of current nodes, one string per node 
-     *         (non-recursive). Applicable to elements and attributes 
-     *         (returns their local names), entity references, processing 
-     *         instructions (returns its target), doctypes (returns its public
-     *         ID)</td>
-     *     </tr>
-     *     <tr>
-     *       <td><tt>_nsprefix</tt></td>
-     *       <td>the namespace prefixes of current nodes, one string per node 
-     *         (non-recursive). Applicable to elements and attributes</td>
-     *     </tr>
-     *     <tr>
-     *       <td><tt>_nsuri</tt></td>
-     *       <td>the namespace URIs of current nodes, one string per node 
-     *       (non-recursive). Applicable to elements and attributes</td>
-     *     </tr>
-     *     <tr>
-     *       <td><tt>_parent</tt></td>
-     *       <td>parent elements of current nodes. Applicable to element, 
-     *       attribute, comment, entity, processing instruction.</td>
-     *     </tr>
-     *     <tr>
-     *       <td><tt>_qname</tt></td>
-     *       <td>the qualified names of current nodes in 
-     *         <tt>[namespacePrefix:]localName</tt> form, one string per node 
-     *         (non-recursive). Applicable to elements and attributes</td>
-     *     </tr>
-     *     <tr>
-     *       <td><tt>_registerNamespace(prefix, uri)</tt></td>
-     *       <td>register a XML namespace with the specified prefix and URI for
-     *         the current node list and all node lists that are derived from 
-     *         the current node list. After registering, you can use the
-     *         <tt>nodelist[&quot;prefix:localname&quot;]</tt> or 
-     *         <tt>nodelist[&quot;@prefix:localname&quot;]</tt> syntaxes to 
-     *         reach elements and attributes whose names are namespace-scoped.
-     *         Note that the namespace prefix need not match the actual prefix 
-     *         used by the XML document itself since namespaces are compared 
-     *         solely by their URI.</td>
-     *     </tr>
-     *     <tr>
-     *       <td><tt>_text</tt></td>
-     *       <td>the text of current nodes, one string per node 
-     *         (non-recursive). Applicable to elements, attributes, comments, 
-     *         processing instructions (returns its data) and CDATA sections. 
-     *         The reserved XML characters ('&lt;' and '&amp;') are NOT 
-     *         escaped.</td>
-     *     </tr>
-     *     <tr>
-     *       <td><tt>_type</tt></td>
-     *       <td>Returns a string describing the type of nodes, one
-     *         string per node. The returned values are &quot;attribute&quot;,
-     *         &quot;cdata&quot;, &quot;comment&quot;, &quot;document&quot;,
-     *         &quot;documentType&quot;, &quot;element&quot;, 
-     *         &quot;entity&quot;, &quot;entityReference&quot;, 
-     *         &quot;namespace&quot;, &quot;processingInstruction&quot;, 
-     *         &quot;text&quot;, or &quot;unknown&quot;.</td>
-     *     </tr>
-     *     <tr>
-     *       <td><tt>_unique</tt></td>
-     *       <td>a copy of the current nodes that keeps only the first 
-     *         occurrence of every node, eliminating duplicates. Duplicates can
-     *         occur in the node list by applying uptree-traversals 
-     *         <tt>_parent</tt>, <tt>_ancestor</tt>, <tt>_ancestorOrSelf</tt>,
-     *         and <tt>_document</tt> on a node list with multiple elements. 
-     *         I.e. <tt>foo._children._parent</tt> will return a node list that
-     *         has duplicates of nodes in foo - each node will have the number 
-     *         of occurrences equal to the number of its children. In these 
-     *         cases, use <tt>foo._children._parent._unique</tt> to eliminate 
-     *         duplicates. Applicable to all node types.</td>
-     *     </tr>
-     *     <tr>
-     *       <td>any other key</td>
-     *       <td>element children of current nodes with name matching the key. 
-     *       This allows for convenience child traversal in 
-     *       <tt>book.chapter.title</tt> style syntax. Applicable to document 
-     *       and element nodes.</td>
-     *     </tr>
-     *   </tbody>
-     * </table>
-     * @return a new NodeListModel containing the nodes that result from applying
-     * the operator to this model's nodes.
-     * @see freemarker.template.TemplateHashModel#get(String)
-     */
-    public TemplateModel get(String key) throws TemplateModelException {
-        // Try a built-in navigator operator
-        NodeOperator op = navigator.getOperator(key);
-        String localName = null;
-        String namespaceUri = "";
-        // If not a nav op, then check for special keys.
-        if (op == null && key.length() > 0 && key.charAt(0) == '_') {
-            if (key.equals("_unique")) {
-                return deriveModel(removeDuplicates(nodes));
-            } else if (key.equals("_filterType") || key.equals("_ftype")) {
-                return new FilterByType();
-            } else if (key.equals("_registerNamespace")) {
-                if (namespaces.isShared()) {
-                    namespaces = (Namespaces) namespaces.clone();
-                }
-            }
-        }
-        // Last, do a named child element or attribute lookup 
-        if (op == null) {
-            int colon = key.indexOf(':');
-            if (colon == -1) {
-                // No namespace prefix specified
-                localName = key;
-            } else {
-                // Namespace prefix specified
-                localName = key.substring(colon + 1);
-                String prefix = key.substring(0, colon);
-                namespaceUri = namespaces.translateNamespacePrefixToUri(prefix);
-                if (namespaceUri == null) {
-                    throw new TemplateModelException("Namespace prefix " + prefix + " is not registered.");
-                }
-            }
-            if (localName.charAt(0) == '@') {
-                op = navigator.getAttributeOperator();
-                localName = localName.substring(1);
-            } else {
-                op = navigator.getChildrenOperator();
-            }
-        }
-        List result = new ArrayList();
-        for (Iterator iter = nodes.iterator(); iter.hasNext(); ) {
-            try {
-                op.process(iter.next(), localName, namespaceUri, result);
-            } catch (RuntimeException e) {
-                throw new TemplateModelException(e);
-            }
-        }
-        return deriveModel(result);
-    }
-
-    /**
-     * Returns true if this NodeListModel contains no nodes. 
-     * @see freemarker.template.TemplateHashModel#isEmpty()
-     */
-    public boolean isEmpty() {
-        return nodes.isEmpty();
-    }
-
-    /**
-     * Registers a namespace prefix-URI pair for subsequent use in {@link
-     * #get(String)} as well as for use in XPath expressions.
-     * @param prefix the namespace prefix to use for the namespace
-     * @param uri the namespace URI that identifies the namespace.
-     */
-    public void registerNamespace(String prefix, String uri) {
-        if (namespaces.isShared()) {
-            namespaces = (Namespaces) namespaces.clone();
-        }
-        namespaces.registerNamespace(prefix, uri);
-    }
-    
-    private class FilterByType
-    implements
-        TemplateMethodModel {
-        public Object exec(List arguments) {
-            List filteredNodes = new ArrayList();
-            for (Iterator iter = arguments.iterator(); iter.hasNext(); ) {
-                Object node = iter.next();
-                if (arguments.contains(navigator.getType(node))) {
-                    filteredNodes.add(node);
-                }
-            }
-            return deriveModel(filteredNodes);
-        }
-    }
-
-    private static final List removeDuplicates(List list) {
-        int s = list.size();
-        ArrayList ulist = new ArrayList(s);
-        Set set = new HashSet(s * 4 / 3, .75f);
-        Iterator it = list.iterator();
-        while (it.hasNext()) {
-            Object o = it.next();
-            if (set.add(o)) {
-                ulist.add(o);
-            }
-        }
-        return ulist;
-    }
-
-    private static Class getClass(String className) {
-        try {
-            return ClassUtil.forName(className);
-        } catch (Exception e) {
-            if (LOG.isDebugEnabled()) {
-                LOG.debug("Couldn't load class " + className, e);
-            }
-            return null;
-        }
-    }
-    
-    private static Navigator getNavigator(String navType) {
-        try {
-            return (Navigator) ClassUtil.forName("freemarker.ext.xml._" + 
-                    navType + "Navigator").newInstance();
-        } catch (Throwable t) {
-            if (LOG.isDebugEnabled()) {
-                LOG.debug("Could not load navigator for " + navType, t);
-            }
-            return null;
-        }
-    }
-
-    public TemplateSequenceModel getChildNodes() throws TemplateModelException {
-        return (TemplateSequenceModel) get("_content");
-    }
-
-    public String getNodeName() throws TemplateModelException {
-        return getUniqueText((NodeListModel) get("_name"), "name");
-    }
-
-    public String getNodeNamespace() throws TemplateModelException {
-        return getUniqueText((NodeListModel) get("_nsuri"), "namespace");
-    }
-
-    public String getNodeType() throws TemplateModelException {
-        return getUniqueText((NodeListModel) get("_type"), "type");
-    }
-    public TemplateNodeModel getParentNode() throws TemplateModelException {
-        return (TemplateNodeModel) get("_parent"); 
-    }
-
-    private String getUniqueText(NodeListModel model, String property) throws TemplateModelException {
-        String s1 = null;
-        Set s = null;
-        for (Iterator it = model.nodes.iterator(); it.hasNext(); ) {
-            String s2 = (String) it.next();
-            if (s2 != null) {
-                // No text yet, make this text the current text
-                if (s1 == null) {
-                    s1 = s2;
-                }
-                // else if there's already a text and they differ, start 
-                // accumulating them for an error message
-                else if (!s1.equals(s2)) {
-                    if (s == null) {
-                        s = new HashSet();
-                        s.add(s1);
-                    }
-                    s.add(s2);
-                }
-            }
-        }
-        // If the set for the error messages is empty, return the retval
-        if (s == null) {
-            return s1;
-        }
-        // Else throw an exception signaling ambiguity
-        throw new TemplateModelException(
-            "Value for node " + property + " is ambiguos: " + s);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/xml/NodeOperator.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/xml/NodeOperator.java b/src/main/java/freemarker/ext/xml/NodeOperator.java
deleted file mode 100644
index 27b80b6..0000000
--- a/src/main/java/freemarker/ext/xml/NodeOperator.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  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.
- */
-
-package freemarker.ext.xml;
-
-import java.util.List;
-
-/**
- */
-interface NodeOperator {
-    void process(Object node, String localName, String namespaceUri, List result);
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/xml/_Dom4jNavigator.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/xml/_Dom4jNavigator.java b/src/main/java/freemarker/ext/xml/_Dom4jNavigator.java
deleted file mode 100644
index 747953d..0000000
--- a/src/main/java/freemarker/ext/xml/_Dom4jNavigator.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  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.
- */
-
-package freemarker.ext.xml;
-
-import java.io.StringWriter;
-import java.util.Iterator;
-import java.util.List;
-
-import org.dom4j.Attribute;
-import org.dom4j.Branch;
-import org.dom4j.Document;
-import org.dom4j.DocumentType;
-import org.dom4j.Element;
-import org.dom4j.Node;
-import org.dom4j.ProcessingInstruction;
-import org.dom4j.tree.DefaultAttribute;
-import org.jaxen.Context;
-import org.jaxen.NamespaceContext;
-import org.jaxen.dom4j.Dom4jXPath;
-
-import freemarker.template.TemplateModelException;
-
-/**
- * Don't use this class; it's only public to work around Google App Engine Java
- * compliance issues. FreeMarker developers only: treat this class as package-visible.
- */
-public class _Dom4jNavigator extends Navigator {
-
-    public _Dom4jNavigator() {
-    } 
-
-    @Override
-    void getAsString(Object node, StringWriter sw) {
-        sw.getBuffer().append(((Node) node).asXML());
-    }
-
-    @Override
-    void getChildren(Object node, String localName, String namespaceUri, List result) {
-        if (node instanceof Element) {
-            Element e = (Element) node;
-            if (localName == null) {
-                result.addAll(e.elements());
-            } else {
-                result.addAll(e.elements(e.getQName().getDocumentFactory().createQName(localName, "", namespaceUri)));
-            }
-        } else if (node instanceof Document) {
-            Element root = ((Document) node).getRootElement();
-            if (localName == null || (equal(root.getName(), localName) && equal(root.getNamespaceURI(), namespaceUri))) {
-                result.add(root);
-            }
-        }
-    }
-    
-    @Override
-    void getAttributes(Object node, String localName, String namespaceUri, List result) {
-        if (node instanceof Element) {
-            Element e = (Element) node;
-            if (localName == null) {
-                result.addAll(e.attributes());
-            } else {
-                Attribute attr = e.attribute(e.getQName().getDocumentFactory().createQName(localName, "", namespaceUri)); 
-                if (attr != null) {
-                    result.add(attr);
-                }
-            }
-        } else if (node instanceof ProcessingInstruction) {
-            ProcessingInstruction pi = (ProcessingInstruction) node;
-            if ("target".equals(localName)) {
-                result.add(new DefaultAttribute("target", pi.getTarget()));
-            } else if ("data".equals(localName)) {
-                result.add(new DefaultAttribute("data", pi.getText()));
-            } else {
-                result.add(new DefaultAttribute(localName, pi.getValue(localName)));
-            }
-        } else if (node instanceof DocumentType) {
-            DocumentType doctype = (DocumentType) node;
-            if ("publicId".equals(localName)) {
-                result.add(new DefaultAttribute("publicId", doctype.getPublicID()));
-            } else if ("systemId".equals(localName)) {
-                result.add(new DefaultAttribute("systemId", doctype.getSystemID()));
-            } else if ("elementName".equals(localName)) {
-                result.add(new DefaultAttribute("elementName", doctype.getElementName()));
-            }
-        } 
-    }
-
-    @Override
-    void getDescendants(Object node, List result) {
-        if (node instanceof Branch) {
-            getDescendants((Branch) node, result);
-        }
-    }
-    
-    private void getDescendants(Branch node, List result) {
-        List content = node.content();
-        for (Iterator iter = content.iterator(); iter.hasNext(); ) {
-            Node subnode = (Node) iter.next();
-            if (subnode instanceof Element) {
-                result.add(subnode);
-                getDescendants(subnode, result);
-            }
-        }
-    }
-
-    @Override
-    Object getParent(Object node) {
-        return ((Node) node).getParent();
-    }
-
-    @Override
-    Object getDocument(Object node) {
-        return ((Node) node).getDocument();
-    }
-
-    @Override
-    Object getDocumentType(Object node) {
-        return 
-            node instanceof Document 
-            ? ((Document) node).getDocType()
-            : null; 
-    }
-    
-    @Override
-    void getContent(Object node, List result) {
-        if (node instanceof Branch) {
-            result.addAll(((Branch) node).content());
-        }
-    }
-
-    @Override
-    String getText(Object node) {
-        return ((Node) node).getText();
-    }
-
-    @Override
-    String getLocalName(Object node) {
-        return ((Node) node).getName();
-    }
-
-    @Override
-    String getNamespacePrefix(Object node) {
-        if (node instanceof Element) {
-            return ((Element) node).getNamespacePrefix();
-        }
-        if (node instanceof Attribute) {
-            return ((Attribute) node).getNamespacePrefix();
-        }
-        return null;
-    }
-
-    @Override
-    String getNamespaceUri(Object node) {
-        if (node instanceof Element) {
-            return ((Element) node).getNamespaceURI();
-        }
-        if (node instanceof Attribute) {
-            return ((Attribute) node).getNamespaceURI();
-        }
-        return null;
-    }
-
-    @Override
-    String getType(Object node) {
-        switch(((Node) node).getNodeType()) {
-            case Node.ATTRIBUTE_NODE: {
-                return "attribute";
-            }
-            case Node.CDATA_SECTION_NODE: {
-                return "cdata";
-            }
-            case Node.COMMENT_NODE: {
-                return "comment";
-            }
-            case Node.DOCUMENT_NODE: {
-                return "document";
-            }
-            case Node.DOCUMENT_TYPE_NODE: {
-                return "documentType";
-            }
-            case Node.ELEMENT_NODE: {
-                return "element";
-            }
-            case Node.ENTITY_REFERENCE_NODE: {
-                return "entityReference";
-            }
-            case Node.NAMESPACE_NODE: {
-                return "namespace";
-            }
-            case Node.PROCESSING_INSTRUCTION_NODE: {
-                return "processingInstruction";
-            }
-            case Node.TEXT_NODE: {
-                return "text";
-            }
-        }
-        return "unknown";
-    }
-
-    @Override
-    XPathEx createXPathEx(String xpathString) throws TemplateModelException {
-        try {
-            return new Dom4jXPathEx(xpathString);
-        } catch (Exception e) {
-            throw new TemplateModelException(e);
-        }
-    }
-
-    private static final class Dom4jXPathEx
-    extends
-        Dom4jXPath
-    implements
-        XPathEx {
-        Dom4jXPathEx(String path)
-        throws Exception {
-            super(path);
-        }
-
-        public List selectNodes(Object object, NamespaceContext namespaces)
-        throws TemplateModelException {
-            Context context = getContext(object);
-            context.getContextSupport().setNamespaceContext(namespaces);
-            try {
-                return selectNodesForContext(context);
-            } catch (Exception e) {
-                throw new TemplateModelException(e);
-            }
-        } 
-    }
-}