Merge remote-tracking branch 'origin/2.3-gae' into 2.3
diff --git a/.project b/.project
index ccb2812..9949b14 100644
--- a/.project
+++ b/.project
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <projectDescription>
-	<name>FreeMarker-2.3-gae</name>
+	<name>FreeMarker-2.3</name>
 	<comment></comment>
 	<projects>
 	</projects>
diff --git a/build.xml b/build.xml
index 98419ff..5026ef6 100644
--- a/build.xml
+++ b/build.xml
@@ -712,14 +712,13 @@
   </parent>
   
   <groupId>org.freemarker</groupId>
-  <artifactId>freemarker-gae</artifactId>
+  <artifactId>freemarker</artifactId>
   <version>${mavenVersion}</version>
   
   <packaging>jar</packaging>
   
   <name>FreeMarker</name>
   <description>
-    Google App Engine compliant variation of FreeMarker.
     FreeMarker is a "template engine"; a generic tool to generate text output based on templates.
   </description>
   <url>http://freemarker.org/</url>
diff --git a/src/main/java/freemarker/core/FreeMarkerTree.java b/src/main/java/freemarker/core/FreeMarkerTree.java
index 9f25212..b277a93 100644
--- a/src/main/java/freemarker/core/FreeMarkerTree.java
+++ b/src/main/java/freemarker/core/FreeMarkerTree.java
@@ -16,13 +16,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;
 
@@ -33,26 +28,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();
     }
 
@@ -60,55 +42,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;
-        }
-
-        public Enumeration children() {
-            final Enumeration e = element.children();
-            return new Enumeration() {
-                public boolean hasMoreElements() {
-                    return e.hasMoreElements();
-                }
-                public Object nextElement() {
-                    return getNode((TemplateElement) e.nextElement());
-                }
-            };
-        }
-
-        public boolean getAllowsChildren() {
-            return element.getAllowsChildren();
-        }
-
-        public TreeNode getChildAt(int childIndex) {
-            return getNode(element.getChildAt(childIndex));
-        }
-
-        public int getChildCount() {
-            return element.getChildCount();
-        }
-
-        public int getIndex(TreeNode node) {
-            return element.getIndex(((TemplateElementTreeNode) node).element);
-        }
-
-        public TreeNode getParent() {
-            return getNode(element.getParentElement());
-        }
-
-        public boolean isLeaf() {
-            return element.isLeaf();
-        }
-        
-        
-    }
-}
\ No newline at end of file
+}
diff --git a/src/main/java/freemarker/core/TemplateElement.java b/src/main/java/freemarker/core/TemplateElement.java
index 2700243..5c68d61 100644
--- a/src/main/java/freemarker/core/TemplateElement.java
+++ b/src/main/java/freemarker/core/TemplateElement.java
@@ -20,6 +20,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;
@@ -35,7 +37,7 @@
  *             it.
  */
 @Deprecated
-abstract public class TemplateElement extends TemplateObject {
+abstract public class TemplateElement extends TemplateObject implements TreeNode {
 
     private static final int INITIAL_REGULATED_CHILD_BUFFER_CAPACITY = 6;
 
@@ -175,7 +177,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) {
         if (nestedBlock instanceof MixedContent) {
             return nestedBlock.getIndex(node);
         }
@@ -219,7 +225,12 @@
         return Collections.enumeration(Collections.EMPTY_LIST);
     }
 
-    public TemplateElement getChildAt(int index) {
+    /**
+     * @deprecated This method will return {@link TemplateElement} starting from 2.4, as that doesn't require Swing;
+     * don't use it.
+     */
+    @Deprecated
+    public TreeNode getChildAt(int index) {
         if (nestedBlock instanceof MixedContent) {
             return nestedBlock.getChildAt(index);
         }
@@ -260,12 +271,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.
      */
     @Deprecated
-    public TemplateElement getParent() {
+    public TreeNode getParent() {
         return parent;
     }
     
diff --git a/src/main/java/freemarker/debug/impl/RmiDebuggerService.java b/src/main/java/freemarker/debug/impl/RmiDebuggerService.java
index 64f904a..32683ec 100644
--- a/src/main/java/freemarker/debug/impl/RmiDebuggerService.java
+++ b/src/main/java/freemarker/debug/impl/RmiDebuggerService.java
@@ -185,7 +185,7 @@
         if (te == null) {
             return;
         }
-        TemplateElement parent = te.getParent();
+        TemplateElement parent = (TemplateElement) te.getParent();
         DebugBreak db = new DebugBreak(te);
         // TODO: Ensure there always is a parent by making sure
         // that the root element in the template is always a MixedContent
@@ -282,13 +282,13 @@
                 db = (DebugBreak) te;
                 break;
             }
-            te = te.getParent();
+            te = (TemplateElement) te.getParent();
         }
         if (db == null) {
             return;
         }
-        TemplateElement parent = db.getParent(); 
-        parent.setChildAt(parent.getIndex(db), db.getChildAt(0));
+        TemplateElement parent = (TemplateElement) db.getParent(); 
+        parent.setChildAt(parent.getIndex(db), (TemplateElement) db.getChildAt(0));
     }
     
     void removeBreakpoints(String templateName) {
@@ -331,9 +331,9 @@
     private void removeDebugBreaks(TemplateElement te) {
         int count = te.getChildCount();
         for (int i = 0; i < count; ++i) {
-            TemplateElement child = te.getChildAt(i);
+            TemplateElement child = (TemplateElement) te.getChildAt(i);
             while (child instanceof DebugBreak) {
-                TemplateElement dbchild = child.getChildAt(0); 
+                TemplateElement dbchild = (TemplateElement) child.getChildAt(0); 
                 te.setChildAt(i, dbchild);
                 child = dbchild;
             }
diff --git a/src/main/java/freemarker/template/Template.java b/src/main/java/freemarker/template/Template.java
index 8ce8c18..51ddce8 100644
--- a/src/main/java/freemarker/template/Template.java
+++ b/src/main/java/freemarker/template/Template.java
@@ -33,6 +33,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;
@@ -977,7 +979,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)) {
@@ -991,7 +993,10 @@
             }
             break;
         }
-        return elements.isEmpty() ? null : elements;
+        if (elements.isEmpty()) {
+            return null;
+        }
+        return new TreePath(elements.toArray());
     }
 
     /**
diff --git a/src/main/resources/freemarker/version.properties b/src/main/resources/freemarker/version.properties
index ba5c76d..3c7c45d 100644
--- a/src/main/resources/freemarker/version.properties
+++ b/src/main/resources/freemarker/version.properties
@@ -80,4 +80,4 @@
 # This should be automatically filled by the building tool (Ant).
 buildTimestamp=@timestampNice@
 
-isGAECompliant=true
+isGAECompliant=false
diff --git a/src/test/java/freemarker/test/TreeView.java b/src/test/java/freemarker/test/TreeView.java
index f1ecf42..654016c 100644
--- a/src/test/java/freemarker/test/TreeView.java
+++ b/src/test/java/freemarker/test/TreeView.java
@@ -61,7 +61,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>");
     }
 }