Merge remote-tracking branch 'origin/2.3-gae' into 2.3
diff --git a/README.md b/README.md
index ea2fb9d..67b0bbb 100644
--- a/README.md
+++ b/README.md
@@ -62,7 +62,7 @@
   -->
   <dependency>
     <groupId>org.freemarker</groupId>
-    <artifactId>freemarker-gae</artifactId>
+    <artifactId>freemarker</artifactId>
     <version>{version}</version>
   </dependency>
 ```
diff --git a/freemarker-core/src/main/java/freemarker/core/FreeMarkerTree.java b/freemarker-core/src/main/java/freemarker/core/FreeMarkerTree.java
index 6d49ea1..b98cae5 100644
--- a/freemarker-core/src/main/java/freemarker/core/FreeMarkerTree.java
+++ b/freemarker-core/src/main/java/freemarker/core/FreeMarkerTree.java
@@ -19,13 +19,8 @@
 
 package freemarker.core;
 
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Map;
-
 import javax.swing.JTree;
 import javax.swing.tree.DefaultTreeModel;
-import javax.swing.tree.TreeNode;
 
 import freemarker.template.Template;
 
@@ -36,26 +31,13 @@
  */
 @Deprecated
 public class FreeMarkerTree extends JTree {
-    private static final long serialVersionUID = 1L;
 
-    private final Map nodeMap = new HashMap();
-    
     public FreeMarkerTree(Template template) {
-        setTemplate(template);
-    }
-
-    private TreeNode getNode(TemplateElement element) {
-        TreeNode n = (TreeNode) nodeMap.get(element);
-        if (n != null) {
-            return n;
-        }
-        n = new TemplateElementTreeNode(element);
-        nodeMap.put(element, n);
-        return n;
+        super(template.getRootTreeNode());
     }
 
     public void setTemplate(Template template) {
-        this.setModel(new DefaultTreeModel(getNode(template.getRootTreeNode())));
+        this.setModel(new DefaultTreeModel(template.getRootTreeNode()));
         this.invalidate();
     }
 
@@ -63,64 +45,10 @@
     public String convertValueToText(Object value, boolean selected,
                                      boolean expanded, boolean leaf, int row,
                                      boolean hasFocus) {
-        if (value instanceof TemplateElementTreeNode) {
-            return ((TemplateElementTreeNode) value).element.getDescription();
+        if (value instanceof TemplateElement) {
+            return ((TemplateElement) value).getDescription();
         }
         return value.toString();
     }
     
-    private class TemplateElementTreeNode implements TreeNode {
-        private final TemplateElement element;
-        
-        TemplateElementTreeNode(TemplateElement element) {
-            this.element = element;
-        }
-
-        @Override
-        public Enumeration children() {
-            final Enumeration e = element.children();
-            return new Enumeration() {
-                @Override
-                public boolean hasMoreElements() {
-                    return e.hasMoreElements();
-                }
-                @Override
-                public Object nextElement() {
-                    return getNode((TemplateElement) e.nextElement());
-                }
-            };
-        }
-
-        @Override
-        public boolean getAllowsChildren() {
-            return element.getAllowsChildren();
-        }
-
-        @Override
-        public TreeNode getChildAt(int childIndex) {
-            return getNode(element.getChildAt(childIndex));
-        }
-
-        @Override
-        public int getChildCount() {
-            return element.getChildCount();
-        }
-
-        @Override
-        public int getIndex(TreeNode node) {
-            return element.getIndex(((TemplateElementTreeNode) node).element);
-        }
-
-        @Override
-        public TreeNode getParent() {
-            return getNode(element.getParentElement());
-        }
-
-        @Override
-        public boolean isLeaf() {
-            return element.isLeaf();
-        }
-        
-        
-    }
-}
\ No newline at end of file
+}
diff --git a/freemarker-core/src/main/java/freemarker/core/TemplateElement.java b/freemarker-core/src/main/java/freemarker/core/TemplateElement.java
index 2e79d93..42948e4 100644
--- a/freemarker-core/src/main/java/freemarker/core/TemplateElement.java
+++ b/freemarker-core/src/main/java/freemarker/core/TemplateElement.java
@@ -23,6 +23,8 @@
 import java.util.Collections;
 import java.util.Enumeration;
 
+import javax.swing.tree.TreeNode;
+
 import freemarker.template.SimpleSequence;
 import freemarker.template.TemplateException;
 import freemarker.template.TemplateNodeModel;
@@ -37,7 +39,8 @@
  *             it.
  */
 @Deprecated
-abstract public class TemplateElement extends TemplateObject implements TemplateProcessingTracer.TracedElement {
+abstract public class TemplateElement extends TemplateObject implements TreeNode,
+        TemplateProcessingTracer.TracedElement {
 
     private static final int INITIAL_REGULATED_CHILD_BUFFER_CAPACITY = 6;
 
@@ -201,7 +204,11 @@
         return !isLeaf();
     }
 
-    public int getIndex(TemplateElement node) {
+    /**
+     * @deprecated Starting from 2.4, we won't use {@link TreeNode} API, as it requires Swing.
+     */
+    @Deprecated
+    public int getIndex(TreeNode node) {
         for (int i = 0; i < childCount; i++) {
             if (childBuffer[i].equals(node)) {
                 return i;
@@ -225,10 +232,11 @@
     }
 
     /**
-     * @deprecated Internal API - even internally, use {@link #getChild(int)} instead.
+     * @deprecated This method will return {@link TemplateElement} starting from 2.4, as that doesn't require Swing;
+     * don't use it. Internally, use {@link #getChild(int)} instead.
      */
     @Deprecated
-    public TemplateElement getChildAt(int index) {
+    public TreeNode getChildAt(int index) {
         if (childCount == 0) {
             throw new IndexOutOfBoundsException("Template element has no children");
         }
@@ -253,10 +261,11 @@
     /**
      * The element whose child this element is, or {@code null} if this is the root node.
      * 
-     * @deprecated Don't use in internal code either; use {@link #getParentElement()} there.
+     * @deprecated This method will return {@link TemplateElement} starting from 2.4, as that doesn't require Swing;
+     * don't use it. Don't use in internal code either; use {@link #getParentElement()} there.
      */
     @Deprecated
-    public TemplateElement getParent() {
+    public TreeNode getParent() {
         return parent;
     }
     
diff --git a/freemarker-core/src/main/java/freemarker/template/Template.java b/freemarker-core/src/main/java/freemarker/template/Template.java
index c6fcc31..655da0a 100644
--- a/freemarker-core/src/main/java/freemarker/template/Template.java
+++ b/freemarker-core/src/main/java/freemarker/template/Template.java
@@ -37,6 +37,8 @@
 import java.util.Map;
 import java.util.Vector;
 
+import javax.swing.tree.TreePath;
+
 import freemarker.cache.TemplateCache;
 import freemarker.cache.TemplateLoader;
 import freemarker.cache.TemplateLookupStrategy;
@@ -1016,7 +1018,7 @@
      * @deprecated Should only be used internally, and might will be removed later.
      */
     @Deprecated
-    public List containingElements(int column, int line) {
+    public TreePath containingElements(int column, int line) {
         final ArrayList elements = new ArrayList();
         TemplateElement element = rootElement;
         mainloop: while (element.contains(column, line)) {
@@ -1030,7 +1032,10 @@
             }
             break;
         }
-        return elements.isEmpty() ? null : elements;
+        if (elements.isEmpty()) {
+            return null;
+        }
+        return new TreePath(elements.toArray());
     }
 
     /**
diff --git a/freemarker-core/src/main/resource-templates/freemarker/version.properties b/freemarker-core/src/main/resource-templates/freemarker/version.properties
index cecfdf7..742177d 100644
--- a/freemarker-core/src/main/resource-templates/freemarker/version.properties
+++ b/freemarker-core/src/main/resource-templates/freemarker/version.properties
@@ -95,4 +95,4 @@
 versionForMf=2.3.32.97
 
 
-isGAECompliant=true
+isGAECompliant=false
diff --git a/freemarker-core/src/test/java/freemarker/test/TreeView.java b/freemarker-core/src/test/java/freemarker/test/TreeView.java
index 0c89f5f..83c0735 100644
--- a/freemarker-core/src/test/java/freemarker/test/TreeView.java
+++ b/freemarker-core/src/test/java/freemarker/test/TreeView.java
@@ -64,7 +64,7 @@
     }
 
     static void usage() {
-        System.err.println("little toy program to display a compiled template as a tree.");
-        System.err.println("Usage: java freemarker.test.TreeView <templatefile>");
+        System.err.println("Little toy program to display a compiled template as a tree.");
+        System.err.println("Usage: java freemarker.testcase.TreeView <templatefile>");
     }
 }
diff --git a/settings.gradle.kts b/settings.gradle.kts
index e74adfb..4bc6ef8 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-rootProject.name = "freemarker-gae"
+rootProject.name = "freemarker"
 
 apply(from = rootDir.toPath().resolve("gradle").resolve("repositories.gradle.kts"))