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/03/01 18:39:05 UTC

[1/5] incubator-freemarker git commit: (Fixed partial copyright headers in some files)

Repository: incubator-freemarker
Updated Branches:
  refs/heads/3 079ff48a7 -> 6939fd075


(Fixed partial copyright headers in some files)


Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/92ea6b51
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/92ea6b51
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/92ea6b51

Branch: refs/heads/3
Commit: 92ea6b51c8b4d9876c350a1dd856fd12e9626af2
Parents: 079ff48
Author: ddekany <dd...@apache.org>
Authored: Wed Mar 1 16:57:30 2017 +0100
Committer: ddekany <dd...@apache.org>
Committed: Wed Mar 1 16:57:30 2017 +0100

----------------------------------------------------------------------
 src/main/misc/overloadedNumberRules/config.fmpp             | 9 +++++++++
 .../freemarker/core/model/impl/unsafeMethods.properties     | 9 +++++++++
 .../resources/org/apache/freemarker/core/version.properties | 9 +++++++++
 .../manualtest/ConfigureOutputFormatExamples1.properties    | 9 +++++++++
 .../manualtest/ConfigureOutputFormatExamples2.properties    | 9 +++++++++
 .../manualtest/TemplateConfigurationExamples1.properties    | 9 +++++++++
 .../manualtest/TemplateConfigurationExamples2.properties    | 9 +++++++++
 .../manualtest/TemplateConfigurationExamples3.properties    | 9 +++++++++
 .../test/templatesuite/models/BeansTestResources.properties | 9 +++++++++
 9 files changed, 81 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/92ea6b51/src/main/misc/overloadedNumberRules/config.fmpp
----------------------------------------------------------------------
diff --git a/src/main/misc/overloadedNumberRules/config.fmpp b/src/main/misc/overloadedNumberRules/config.fmpp
index cf32e92..50aacbb 100644
--- a/src/main/misc/overloadedNumberRules/config.fmpp
+++ b/src/main/misc/overloadedNumberRules/config.fmpp
@@ -14,6 +14,15 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+#
+#   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.
 
 sources: generator.ftl
 outputFile: ../../../../build/overloadedNumberRules.java

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/92ea6b51/src/main/resources/org/apache/freemarker/core/model/impl/unsafeMethods.properties
----------------------------------------------------------------------
diff --git a/src/main/resources/org/apache/freemarker/core/model/impl/unsafeMethods.properties b/src/main/resources/org/apache/freemarker/core/model/impl/unsafeMethods.properties
index 05c1981..916d2f4 100644
--- a/src/main/resources/org/apache/freemarker/core/model/impl/unsafeMethods.properties
+++ b/src/main/resources/org/apache/freemarker/core/model/impl/unsafeMethods.properties
@@ -14,6 +14,15 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+#
+#   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.
 
 java.lang.Object.wait()
 java.lang.Object.wait(long)

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/92ea6b51/src/main/resources/org/apache/freemarker/core/version.properties
----------------------------------------------------------------------
diff --git a/src/main/resources/org/apache/freemarker/core/version.properties b/src/main/resources/org/apache/freemarker/core/version.properties
index 2edcf88..1122bd7 100644
--- a/src/main/resources/org/apache/freemarker/core/version.properties
+++ b/src/main/resources/org/apache/freemarker/core/version.properties
@@ -14,6 +14,15 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+#
+#   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.
 
 # Version info for the builds.
 

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/92ea6b51/src/test/resources/org/apache/freemarker/manualtest/ConfigureOutputFormatExamples1.properties
----------------------------------------------------------------------
diff --git a/src/test/resources/org/apache/freemarker/manualtest/ConfigureOutputFormatExamples1.properties b/src/test/resources/org/apache/freemarker/manualtest/ConfigureOutputFormatExamples1.properties
index 0df9e33..601ce15 100644
--- a/src/test/resources/org/apache/freemarker/manualtest/ConfigureOutputFormatExamples1.properties
+++ b/src/test/resources/org/apache/freemarker/manualtest/ConfigureOutputFormatExamples1.properties
@@ -14,6 +14,15 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+#
+#   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.
 
 templateConfigurations = \
     ConditionalTemplateConfigurationFactory( \

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/92ea6b51/src/test/resources/org/apache/freemarker/manualtest/ConfigureOutputFormatExamples2.properties
----------------------------------------------------------------------
diff --git a/src/test/resources/org/apache/freemarker/manualtest/ConfigureOutputFormatExamples2.properties b/src/test/resources/org/apache/freemarker/manualtest/ConfigureOutputFormatExamples2.properties
index 5d2a738..0179466 100644
--- a/src/test/resources/org/apache/freemarker/manualtest/ConfigureOutputFormatExamples2.properties
+++ b/src/test/resources/org/apache/freemarker/manualtest/ConfigureOutputFormatExamples2.properties
@@ -14,6 +14,15 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+#
+#   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.
 
 templateConfigurations = \
     FirstMatchTemplateConfigurationFactory( \

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/92ea6b51/src/test/resources/org/apache/freemarker/manualtest/TemplateConfigurationExamples1.properties
----------------------------------------------------------------------
diff --git a/src/test/resources/org/apache/freemarker/manualtest/TemplateConfigurationExamples1.properties b/src/test/resources/org/apache/freemarker/manualtest/TemplateConfigurationExamples1.properties
index cffadfb..24e9747 100644
--- a/src/test/resources/org/apache/freemarker/manualtest/TemplateConfigurationExamples1.properties
+++ b/src/test/resources/org/apache/freemarker/manualtest/TemplateConfigurationExamples1.properties
@@ -14,6 +14,15 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+#
+#   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.
 
 templateConfigurations = \
     ConditionalTemplateConfigurationFactory( \

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/92ea6b51/src/test/resources/org/apache/freemarker/manualtest/TemplateConfigurationExamples2.properties
----------------------------------------------------------------------
diff --git a/src/test/resources/org/apache/freemarker/manualtest/TemplateConfigurationExamples2.properties b/src/test/resources/org/apache/freemarker/manualtest/TemplateConfigurationExamples2.properties
index f879e70..b5619f0 100644
--- a/src/test/resources/org/apache/freemarker/manualtest/TemplateConfigurationExamples2.properties
+++ b/src/test/resources/org/apache/freemarker/manualtest/TemplateConfigurationExamples2.properties
@@ -14,6 +14,15 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+#
+#   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.
 
 templateConfigurations = \
     ConditionalTemplateConfigurationFactory( \

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/92ea6b51/src/test/resources/org/apache/freemarker/manualtest/TemplateConfigurationExamples3.properties
----------------------------------------------------------------------
diff --git a/src/test/resources/org/apache/freemarker/manualtest/TemplateConfigurationExamples3.properties b/src/test/resources/org/apache/freemarker/manualtest/TemplateConfigurationExamples3.properties
index cf4c5a4..1cd1b26 100644
--- a/src/test/resources/org/apache/freemarker/manualtest/TemplateConfigurationExamples3.properties
+++ b/src/test/resources/org/apache/freemarker/manualtest/TemplateConfigurationExamples3.properties
@@ -14,6 +14,15 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+#
+#   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.
 
 templateConfigurations = \
     MergingTemplateConfigurationFactory( \

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/92ea6b51/src/test/resources/org/apache/freemarker/test/templatesuite/models/BeansTestResources.properties
----------------------------------------------------------------------
diff --git a/src/test/resources/org/apache/freemarker/test/templatesuite/models/BeansTestResources.properties b/src/test/resources/org/apache/freemarker/test/templatesuite/models/BeansTestResources.properties
index 609e20b..32190a8 100644
--- a/src/test/resources/org/apache/freemarker/test/templatesuite/models/BeansTestResources.properties
+++ b/src/test/resources/org/apache/freemarker/test/templatesuite/models/BeansTestResources.properties
@@ -14,6 +14,15 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+#
+#   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.
 
 message=Message
 format={0,date,yyyy-MM-dd}
\ No newline at end of file


[5/5] incubator-freemarker git commit: Moved debug feature into a single package.

Posted by dd...@apache.org.
Moved debug feature into a single package.


Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/6939fd07
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/6939fd07
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/6939fd07

Branch: refs/heads/3
Commit: 6939fd075a3188594d94582fac892b032eb92d2d
Parents: 64ca9c2
Author: ddekany <dd...@apache.org>
Authored: Wed Mar 1 19:38:54 2017 +0100
Committer: ddekany <dd...@apache.org>
Committed: Wed Mar 1 19:38:54 2017 +0100

----------------------------------------------------------------------
 .../apache/freemarker/core/ASTDebugBreak.java   |   4 +-
 .../apache/freemarker/core/Configuration.java   |  13 +-
 .../org/apache/freemarker/core/Template.java    |   6 +-
 .../freemarker/core/debug/DebuggerClient.java   |   1 -
 .../freemarker/core/debug/DebuggerServer.java   | 130 +++++++
 .../core/debug/RmiDebugModelImpl.java           | 164 +++++++++
 .../core/debug/RmiDebuggedEnvironmentImpl.java  | 335 ++++++++++++++++++
 .../freemarker/core/debug/RmiDebuggerImpl.java  |  86 +++++
 .../core/debug/RmiDebuggerListenerImpl.java     |  67 ++++
 .../core/debug/RmiDebuggerService.java          | 307 +++++++++++++++++
 .../apache/freemarker/core/debug/SoftCache.java |  89 +++++
 .../freemarker/core/debug/_DebuggerService.java |  93 +++++
 .../core/debug/impl/DebuggerServer.java         | 130 -------
 .../core/debug/impl/DebuggerService.java        |  93 -----
 .../core/debug/impl/RmiDebugModelImpl.java      | 165 ---------
 .../debug/impl/RmiDebuggedEnvironmentImpl.java  | 337 -------------------
 .../core/debug/impl/RmiDebuggerImpl.java        |  90 -----
 .../debug/impl/RmiDebuggerListenerImpl.java     |  67 ----
 .../core/debug/impl/RmiDebuggerService.java     | 310 -----------------
 .../freemarker/core/debug/impl/SoftCache.java   |  89 -----
 20 files changed, 1288 insertions(+), 1288 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/6939fd07/src/main/java/org/apache/freemarker/core/ASTDebugBreak.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/ASTDebugBreak.java b/src/main/java/org/apache/freemarker/core/ASTDebugBreak.java
index b85c10b..fe42f41 100644
--- a/src/main/java/org/apache/freemarker/core/ASTDebugBreak.java
+++ b/src/main/java/org/apache/freemarker/core/ASTDebugBreak.java
@@ -21,7 +21,7 @@ package org.apache.freemarker.core;
 
 import java.io.IOException;
 
-import org.apache.freemarker.core.debug.impl.DebuggerService;
+import org.apache.freemarker.core.debug._DebuggerService;
 
 /**
  * AST node: A debug breakpoint
@@ -34,7 +34,7 @@ class ASTDebugBreak extends ASTElement {
     
     @Override
     protected ASTElement[] accept(Environment env) throws TemplateException, IOException {
-        if (!DebuggerService.suspendEnvironment(
+        if (!_DebuggerService.suspendEnvironment(
                 env, getTemplate().getSourceName(), getChild(0).getBeginLine())) {
             return getChild(0).accept(env);
         } else {

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/6939fd07/src/main/java/org/apache/freemarker/core/Configuration.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/Configuration.java b/src/main/java/org/apache/freemarker/core/Configuration.java
index b85dacc..6b256b6 100644
--- a/src/main/java/org/apache/freemarker/core/Configuration.java
+++ b/src/main/java/org/apache/freemarker/core/Configuration.java
@@ -36,6 +36,7 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Properties;
 import java.util.Set;
+import java.util.TimeZone;
 import java.util.TreeSet;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
@@ -489,6 +490,11 @@ public class Configuration extends Configurable implements Cloneable, ParserConf
         loadBuiltInSharedVariables();
     }
 
+    @Override
+    public void setTimeZone(TimeZone timeZone) {
+        super.setTimeZone(timeZone);
+    }
+
     private void createTemplateResolver() {
         templateResolver = new DefaultTemplateResolver(
                 null,
@@ -500,7 +506,12 @@ public class Configuration extends Configurable implements Cloneable, ParserConf
         templateResolver.clearTemplateCache(); // for fully BC behavior
         templateResolver.setTemplateUpdateDelayMilliseconds(5000);
     }
-    
+
+    @Override
+    public TemplateExceptionHandler getTemplateExceptionHandler() {
+        return super.getTemplateExceptionHandler();
+    }
+
     private void recreateTemplateResolverWith(
             TemplateLoader loader, CacheStorage storage,
             TemplateLookupStrategy templateLookupStrategy, TemplateNameFormat templateNameFormat,

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/6939fd07/src/main/java/org/apache/freemarker/core/Template.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/Template.java b/src/main/java/org/apache/freemarker/core/Template.java
index 87940a8..7b981af 100644
--- a/src/main/java/org/apache/freemarker/core/Template.java
+++ b/src/main/java/org/apache/freemarker/core/Template.java
@@ -37,7 +37,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Vector;
 
-import org.apache.freemarker.core.debug.impl.DebuggerService;
+import org.apache.freemarker.core.debug._DebuggerService;
 import org.apache.freemarker.core.model.ObjectWrapper;
 import org.apache.freemarker.core.model.TemplateHashModel;
 import org.apache.freemarker.core.model.TemplateModel;
@@ -279,7 +279,7 @@ public class Template extends Configurable {
         // Throws any exception that JavaCC has silently treated as EOF:
         ltbReader.throwFailure();
         
-        DebuggerService.registerTemplate(this);
+        _DebuggerService.registerTemplate(this);
         namespaceURIToPrefixLookup = Collections.unmodifiableMap(namespaceURIToPrefixLookup);
         prefixToNamespaceURILookup = Collections.unmodifiableMap(prefixToNamespaceURILookup);
     }
@@ -318,7 +318,7 @@ public class Template extends Configurable {
         ((ASTStaticText) template.rootElement).replaceText(content);
         template.setEncoding(encoding);
 
-        DebuggerService.registerTemplate(template);
+        _DebuggerService.registerTemplate(template);
 
         return template;
     }

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/6939fd07/src/main/java/org/apache/freemarker/core/debug/DebuggerClient.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/debug/DebuggerClient.java b/src/main/java/org/apache/freemarker/core/debug/DebuggerClient.java
index 1aa740d..a4612e2 100644
--- a/src/main/java/org/apache/freemarker/core/debug/DebuggerClient.java
+++ b/src/main/java/org/apache/freemarker/core/debug/DebuggerClient.java
@@ -30,7 +30,6 @@ import java.security.MessageDigest;
 import java.util.Collection;
 import java.util.List;
 
-import org.apache.freemarker.core.debug.impl.RmiDebuggerListenerImpl;
 import org.apache.freemarker.core.util.UndeclaredThrowableException;
 
 /**

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/6939fd07/src/main/java/org/apache/freemarker/core/debug/DebuggerServer.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/debug/DebuggerServer.java b/src/main/java/org/apache/freemarker/core/debug/DebuggerServer.java
new file mode 100644
index 0000000..d142d16
--- /dev/null
+++ b/src/main/java/org/apache/freemarker/core/debug/DebuggerServer.java
@@ -0,0 +1,130 @@
+/*
+ * 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 org.apache.freemarker.core.debug;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.io.UnsupportedEncodingException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.security.MessageDigest;
+import java.security.SecureRandom;
+import java.util.Arrays;
+import java.util.Random;
+
+import org.apache.freemarker.core._CoreLogs;
+import org.apache.freemarker.core.debug.Debugger;
+import org.apache.freemarker.core.util.UndeclaredThrowableException;
+import org.apache.freemarker.core.util._SecurityUtil;
+import org.slf4j.Logger;
+
+/**
+ */
+class DebuggerServer {
+
+    private static final Logger LOG = _CoreLogs.DEBUG_SERVER;
+    
+    // TODO: Eventually replace with Yarrow    
+    // TODO: Can be extremely slow (on Linux, not enough entropy)
+    private static final Random R = new SecureRandom();
+    
+    private final byte[] password;
+    private final int port;
+    private final Serializable debuggerStub;
+    private boolean stop = false;
+    private ServerSocket serverSocket;
+    
+    public DebuggerServer(Serializable debuggerStub) {
+        port = _SecurityUtil.getSystemProperty("org.apache.freemarker.core.debug.port", Debugger.DEFAULT_PORT).intValue();
+        try {
+            password = _SecurityUtil.getSystemProperty("org.apache.freemarker.core.debug.password", "").getBytes("UTF-8");
+        } catch (UnsupportedEncodingException e) {
+            throw new UndeclaredThrowableException(e);
+        }
+        this.debuggerStub = debuggerStub;
+    }
+    
+    public void start() {
+        new Thread(new Runnable()
+        {
+            @Override
+            public void run() {
+                startInternal();
+            }
+        }, "FreeMarker Debugger Server Acceptor").start();
+    }
+    
+    private void startInternal() {
+        try {
+            serverSocket = new ServerSocket(port);
+            while (!stop) {
+                Socket s = serverSocket.accept();
+                new Thread(new DebuggerAuthProtocol(s)).start();
+            }
+        } catch (IOException e) {
+            LOG.error("Debugger server shut down.", e);
+        }
+    }
+    
+    private class DebuggerAuthProtocol implements Runnable {
+        private final Socket s;
+        
+        DebuggerAuthProtocol(Socket s) {
+            this.s = s;
+        }
+        
+        @Override
+        public void run() {
+            try {
+                ObjectOutputStream out = new ObjectOutputStream(s.getOutputStream());
+                ObjectInputStream in = new ObjectInputStream(s.getInputStream());
+                byte[] challenge = new byte[512];
+                R.nextBytes(challenge);
+                out.writeInt(220); // protocol version
+                out.writeObject(challenge);
+                MessageDigest md = MessageDigest.getInstance("SHA");
+                md.update(password);
+                md.update(challenge);
+                byte[] response = (byte[]) in.readObject();
+                if (Arrays.equals(response, md.digest())) {
+                    out.writeObject(debuggerStub);
+                } else {
+                    out.writeObject(null);
+                }
+            } catch (Exception e) {
+                LOG.warn("Connection to {} abruptly broke", s.getInetAddress().getHostAddress(), e);
+            }
+        }
+
+    }
+
+    public void stop() {
+        stop = true;
+        if (serverSocket != null) {
+            try {
+                serverSocket.close();
+            } catch (IOException e) {
+                LOG.error("Unable to close server socket.", e);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/6939fd07/src/main/java/org/apache/freemarker/core/debug/RmiDebugModelImpl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/debug/RmiDebugModelImpl.java b/src/main/java/org/apache/freemarker/core/debug/RmiDebugModelImpl.java
new file mode 100644
index 0000000..bb11db3
--- /dev/null
+++ b/src/main/java/org/apache/freemarker/core/debug/RmiDebugModelImpl.java
@@ -0,0 +1,164 @@
+/*
+ * 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 org.apache.freemarker.core.debug;
+
+import java.rmi.RemoteException;
+import java.rmi.server.UnicastRemoteObject;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.freemarker.core.model.TemplateBooleanModel;
+import org.apache.freemarker.core.model.TemplateCollectionModel;
+import org.apache.freemarker.core.model.TemplateDateModel;
+import org.apache.freemarker.core.model.TemplateHashModel;
+import org.apache.freemarker.core.model.TemplateHashModelEx;
+import org.apache.freemarker.core.model.TemplateMethodModel;
+import org.apache.freemarker.core.model.TemplateMethodModelEx;
+import org.apache.freemarker.core.model.TemplateModel;
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.model.TemplateModelIterator;
+import org.apache.freemarker.core.model.TemplateNumberModel;
+import org.apache.freemarker.core.model.TemplateScalarModel;
+import org.apache.freemarker.core.model.TemplateSequenceModel;
+import org.apache.freemarker.core.model.TemplateTransformModel;
+
+/**
+ */
+class RmiDebugModelImpl extends UnicastRemoteObject implements DebugModel {
+    private static final long serialVersionUID = 1L;
+
+    private final TemplateModel model;
+    private final int type;
+    
+    RmiDebugModelImpl(TemplateModel model, int extraTypes) throws RemoteException {
+        super();
+        this.model = model;
+        type = calculateType(model) + extraTypes;
+    }
+
+    private static DebugModel getDebugModel(TemplateModel tm) throws RemoteException {
+        return (DebugModel) RmiDebuggedEnvironmentImpl.getCachedWrapperFor(tm);
+    }
+    @Override
+    public String getAsString() throws TemplateModelException {
+        return ((TemplateScalarModel) model).getAsString();
+    }
+
+    @Override
+    public Number getAsNumber() throws TemplateModelException {
+        return ((TemplateNumberModel) model).getAsNumber();
+    }
+
+    @Override
+    public Date getAsDate() throws TemplateModelException {
+        return ((TemplateDateModel) model).getAsDate();
+    }
+
+    @Override
+    public int getDateType() {
+        return ((TemplateDateModel) model).getDateType();
+    }
+
+    @Override
+    public boolean getAsBoolean() throws TemplateModelException {
+        return ((TemplateBooleanModel) model).getAsBoolean();
+    }
+
+    @Override
+    public int size() throws TemplateModelException {
+        if (model instanceof TemplateSequenceModel) {
+            return ((TemplateSequenceModel) model).size();
+        }
+        return ((TemplateHashModelEx) model).size();
+    }
+
+    @Override
+    public DebugModel get(int index) throws TemplateModelException, RemoteException {
+        return getDebugModel(((TemplateSequenceModel) model).get(index));
+    }
+    
+    @Override
+    public DebugModel[] get(int fromIndex, int toIndex) throws TemplateModelException, RemoteException {
+        DebugModel[] dm = new DebugModel[toIndex - fromIndex];
+        TemplateSequenceModel s = (TemplateSequenceModel) model;
+        for (int i = fromIndex; i < toIndex; i++) {
+            dm[i - fromIndex] = getDebugModel(s.get(i));
+        }
+        return dm;
+    }
+
+    @Override
+    public DebugModel[] getCollection() throws TemplateModelException, RemoteException {
+        List list = new ArrayList();
+        TemplateModelIterator i = ((TemplateCollectionModel) model).iterator();
+        while (i.hasNext()) {
+            list.add(getDebugModel(i.next()));
+        }
+        return (DebugModel[]) list.toArray(new DebugModel[list.size()]);
+    }
+    
+    @Override
+    public DebugModel get(String key) throws TemplateModelException, RemoteException {
+        return getDebugModel(((TemplateHashModel) model).get(key));
+    }
+    
+    @Override
+    public DebugModel[] get(String[] keys) throws TemplateModelException, RemoteException {
+        DebugModel[] dm = new DebugModel[keys.length];
+        TemplateHashModel h = (TemplateHashModel) model;
+        for (int i = 0; i < keys.length; i++) {
+            dm[i] = getDebugModel(h.get(keys[i]));
+        }
+        return dm;
+    }
+
+    @Override
+    public String[] keys() throws TemplateModelException {
+        TemplateHashModelEx h = (TemplateHashModelEx) model;
+        List list = new ArrayList();
+        TemplateModelIterator i = h.keys().iterator();
+        while (i.hasNext()) {
+            list.add(((TemplateScalarModel) i.next()).getAsString());
+        }
+        return (String[]) list.toArray(new String[list.size()]);
+    }
+
+    @Override
+    public int getModelTypes() {
+        return type;
+    }
+    
+    private static int calculateType(TemplateModel model) {
+        int type = 0;
+        if (model instanceof TemplateScalarModel) type += TYPE_SCALAR;
+        if (model instanceof TemplateNumberModel) type += TYPE_NUMBER;
+        if (model instanceof TemplateDateModel) type += TYPE_DATE;
+        if (model instanceof TemplateBooleanModel) type += TYPE_BOOLEAN;
+        if (model instanceof TemplateSequenceModel) type += TYPE_SEQUENCE;
+        if (model instanceof TemplateCollectionModel) type += TYPE_COLLECTION;
+        if (model instanceof TemplateHashModelEx) type += TYPE_HASH_EX;
+        else if (model instanceof TemplateHashModel) type += TYPE_HASH;
+        if (model instanceof TemplateMethodModelEx) type += TYPE_METHOD_EX;
+        else if (model instanceof TemplateMethodModel) type += TYPE_METHOD;
+        if (model instanceof TemplateTransformModel) type += TYPE_TRANSFORM;
+        return type;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/6939fd07/src/main/java/org/apache/freemarker/core/debug/RmiDebuggedEnvironmentImpl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/debug/RmiDebuggedEnvironmentImpl.java b/src/main/java/org/apache/freemarker/core/debug/RmiDebuggedEnvironmentImpl.java
new file mode 100644
index 0000000..3229c81
--- /dev/null
+++ b/src/main/java/org/apache/freemarker/core/debug/RmiDebuggedEnvironmentImpl.java
@@ -0,0 +1,335 @@
+/*
+ * 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 org.apache.freemarker.core.debug;
+
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.rmi.server.UnicastRemoteObject;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.IdentityHashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.freemarker.core.Configurable;
+import org.apache.freemarker.core.Configuration;
+import org.apache.freemarker.core.Environment;
+import org.apache.freemarker.core.Template;
+import org.apache.freemarker.core.model.TemplateCollectionModel;
+import org.apache.freemarker.core.model.TemplateHashModelEx;
+import org.apache.freemarker.core.model.TemplateModel;
+import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.model.impl.SimpleCollection;
+import org.apache.freemarker.core.model.impl.SimpleScalar;
+import org.apache.freemarker.core.util.UndeclaredThrowableException;
+
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+
+@SuppressWarnings("serial")
+class RmiDebuggedEnvironmentImpl extends RmiDebugModelImpl implements DebuggedEnvironment {
+
+    private static final SoftCache CACHE = new SoftCache(new IdentityHashMap());
+    private static final Object ID_LOCK = new Object();
+    
+    private static long nextId = 1;
+    private static Set remotes = new HashSet();
+
+    
+    private boolean stopped = false;
+    private final long id;
+    
+    private RmiDebuggedEnvironmentImpl(Environment env) throws RemoteException {
+        super(new DebugEnvironmentModel(env), DebugModel.TYPE_ENVIRONMENT);
+        synchronized (ID_LOCK) {
+            id = nextId++;
+        }
+    }
+
+    static synchronized Object getCachedWrapperFor(Object key)
+    throws RemoteException {
+        Object value = CACHE.get(key);
+        if (value == null) {
+            if (key instanceof TemplateModel) {
+                int extraTypes;
+                if (key instanceof DebugConfigurationModel) {
+                    extraTypes = DebugModel.TYPE_CONFIGURATION;
+                } else if (key instanceof DebugTemplateModel) {
+                    extraTypes = DebugModel.TYPE_TEMPLATE;
+                } else {
+                    extraTypes = 0;
+                }
+                value = new RmiDebugModelImpl((TemplateModel) key, extraTypes);
+            } else if (key instanceof Environment) {
+                value = new RmiDebuggedEnvironmentImpl((Environment) key); 
+            } else if (key instanceof Template) {
+                value = new DebugTemplateModel((Template) key);
+            } else if (key instanceof Configuration) {
+                value = new DebugConfigurationModel((Configuration) key);
+            }
+        }
+        if (value != null) {
+            CACHE.put(key, value);
+        }
+        if (value instanceof Remote) {
+            remotes.add(value);
+        }
+        return value;
+    }
+
+    // TODO See in SuppressFBWarnings
+    @Override
+    @SuppressFBWarnings(value="NN_NAKED_NOTIFY", justification="Will have to be re-desigend; postponed.")
+    public void resume() {
+        synchronized (this) {
+            notify();
+        }
+    }
+
+    @Override
+    public void stop() {
+        stopped = true;
+        resume();
+    }
+
+    @Override
+    public long getId() {
+        return id;
+    }
+    
+    boolean isStopped() {
+        return stopped;
+    }
+    
+    private abstract static class DebugMapModel implements TemplateHashModelEx {
+        @Override
+        public int size() {
+            return keySet().size();
+        }
+
+        @Override
+        public TemplateCollectionModel keys() {
+            return new SimpleCollection(keySet());
+        }
+
+        @Override
+        public TemplateCollectionModel values() throws TemplateModelException {
+            Collection keys = keySet();
+            List list = new ArrayList(keys.size());
+            
+            for (Iterator it = keys.iterator(); it.hasNext(); ) {
+                list.add(get((String) it.next()));
+            }
+            return new SimpleCollection(list);
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return size() == 0;
+        }
+        
+        abstract Collection keySet();
+
+        static List composeList(Collection c1, Collection c2) {
+            List list = new ArrayList(c1);
+            list.addAll(c2);
+            Collections.sort(list);
+            return list;
+        }
+    }
+    
+    private static class DebugConfigurableModel extends DebugMapModel {
+        static final List KEYS = Arrays.asList(
+                Configurable.ARITHMETIC_ENGINE_KEY,
+                Configurable.BOOLEAN_FORMAT_KEY,
+                Configurable.LOCALE_KEY,
+                Configurable.NUMBER_FORMAT_KEY,
+                Configurable.OBJECT_WRAPPER_KEY,
+                Configurable.TEMPLATE_EXCEPTION_HANDLER_KEY);
+
+        final Configurable configurable;
+        
+        DebugConfigurableModel(Configurable configurable) {
+            this.configurable = configurable;
+        }
+        
+        @Override
+        Collection keySet() {
+            return KEYS;
+        }
+        
+        @Override
+        public TemplateModel get(String key) throws TemplateModelException {
+            return null; // TODO
+        }
+
+    }
+    
+    private static class DebugConfigurationModel extends DebugConfigurableModel {
+        private static final List KEYS = composeList(DebugConfigurableModel.KEYS, Collections.singleton("sharedVariables"));
+
+        private TemplateModel sharedVariables = new DebugMapModel()
+        {
+            @Override
+            Collection keySet() {
+                return ((Configuration) configurable).getSharedVariableNames();
+            }
+        
+            @Override
+            public TemplateModel get(String key) {
+                return ((Configuration) configurable).getSharedVariable(key);
+            }
+        };
+        
+        DebugConfigurationModel(Configuration config) {
+            super(config);
+        }
+        
+        @Override
+        Collection keySet() {
+            return KEYS;
+        }
+
+        @Override
+        public TemplateModel get(String key) throws TemplateModelException {
+            if ("sharedVariables".equals(key)) {
+                return sharedVariables; 
+            } else {
+                return super.get(key);
+            }
+        }
+    }
+    
+    private static class DebugTemplateModel extends DebugConfigurableModel {
+        private static final List KEYS = composeList(DebugConfigurableModel.KEYS, 
+            Arrays.asList("configuration", "name"));
+    
+        private final SimpleScalar name;
+
+        DebugTemplateModel(Template template) {
+            super(template);
+            name = new SimpleScalar(template.getName());
+        }
+
+        @Override
+        Collection keySet() {
+            return KEYS;
+        }
+
+        @Override
+        public TemplateModel get(String key) throws TemplateModelException {
+            if ("configuration".equals(key)) {
+                try {
+                    return (TemplateModel) getCachedWrapperFor(((Template) configurable).getConfiguration());
+                } catch (RemoteException e) {
+                    throw new TemplateModelException(e);
+                }
+            }
+            if ("name".equals(key)) {
+                return name;
+            }
+            return super.get(key);
+        }
+    }
+
+    private static class DebugEnvironmentModel extends DebugConfigurableModel {
+        private static final List KEYS = composeList(DebugConfigurableModel.KEYS, 
+            Arrays.asList(
+                    "currentNamespace",
+                    "dataModel",
+                    "globalNamespace",
+                    "knownVariables",
+                    "mainNamespace",
+                    "template"));
+    
+        private TemplateModel knownVariables = new DebugMapModel()
+        {
+            @Override
+            Collection keySet() {
+                try {
+                    return ((Environment) configurable).getKnownVariableNames();
+                } catch (TemplateModelException e) {
+                    throw new UndeclaredThrowableException(e);
+                }
+            }
+        
+            @Override
+            public TemplateModel get(String key) throws TemplateModelException {
+                return ((Environment) configurable).getVariable(key);
+            }
+        };
+         
+        DebugEnvironmentModel(Environment env) {
+            super(env);
+        }
+
+        @Override
+        Collection keySet() {
+            return KEYS;
+        }
+
+        @Override
+        public TemplateModel get(String key) throws TemplateModelException {
+            if ("currentNamespace".equals(key)) {
+                return ((Environment) configurable).getCurrentNamespace();
+            }
+            if ("dataModel".equals(key)) {
+                return ((Environment) configurable).getDataModel();
+            }
+            if ("globalNamespace".equals(key)) {
+                return ((Environment) configurable).getGlobalNamespace();
+            }
+            if ("knownVariables".equals(key)) {
+                return knownVariables;
+            }
+            if ("mainNamespace".equals(key)) {
+                return ((Environment) configurable).getMainNamespace();
+            }
+            if ("mainTemplate".equals(key)) {
+                try {
+                    return (TemplateModel) getCachedWrapperFor(((Environment) configurable).getMainTemplate());
+                } catch (RemoteException e) {
+                    throw new TemplateModelException(e);
+                }
+            }
+            if ("currentTemplate".equals(key)) {
+                try {
+                    return (TemplateModel) getCachedWrapperFor(((Environment) configurable).getCurrentTemplate());
+                } catch (RemoteException e) {
+                    throw new TemplateModelException(e);
+                }
+            }
+            return super.get(key);
+        }
+    }
+
+    public static void cleanup() {
+        for (Iterator i = remotes.iterator(); i.hasNext(); ) {
+            Object remoteObject = i.next();
+            try {
+                UnicastRemoteObject.unexportObject((Remote) remoteObject, true);
+            } catch (Exception e) {
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/6939fd07/src/main/java/org/apache/freemarker/core/debug/RmiDebuggerImpl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/debug/RmiDebuggerImpl.java b/src/main/java/org/apache/freemarker/core/debug/RmiDebuggerImpl.java
new file mode 100644
index 0000000..ea54e4e
--- /dev/null
+++ b/src/main/java/org/apache/freemarker/core/debug/RmiDebuggerImpl.java
@@ -0,0 +1,86 @@
+/*
+ * 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 org.apache.freemarker.core.debug;
+
+import java.rmi.RemoteException;
+import java.rmi.server.UnicastRemoteObject;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ */
+class RmiDebuggerImpl
+extends
+    UnicastRemoteObject
+implements
+    Debugger {
+    private static final long serialVersionUID = 1L;
+
+    private final RmiDebuggerService service;
+    
+    protected RmiDebuggerImpl(RmiDebuggerService service) throws RemoteException {
+        this.service = service;
+    }
+
+    @Override
+    public void addBreakpoint(Breakpoint breakpoint) {
+        service.addBreakpoint(breakpoint);
+    }
+
+    @Override
+    public Object addDebuggerListener(DebuggerListener listener) {
+        return service.addDebuggerListener(listener);
+    }
+
+    @Override
+    public List getBreakpoints() {
+        return service.getBreakpointsSpi();
+    }
+
+    @Override
+    public List getBreakpoints(String templateName) {
+        return service.getBreakpointsSpi(templateName);
+    }
+
+    @Override
+    public Collection getSuspendedEnvironments() {
+        return service.getSuspendedEnvironments();
+    }
+
+    @Override
+    public void removeBreakpoint(Breakpoint breakpoint) {
+        service.removeBreakpoint(breakpoint);
+    }
+
+    @Override
+    public void removeDebuggerListener(Object id) {
+        service.removeDebuggerListener(id);
+    }
+
+    @Override
+    public void removeBreakpoints() {
+        service.removeBreakpoints();
+    }
+
+    @Override
+    public void removeBreakpoints(String templateName) {
+        service.removeBreakpoints(templateName);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/6939fd07/src/main/java/org/apache/freemarker/core/debug/RmiDebuggerListenerImpl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/debug/RmiDebuggerListenerImpl.java b/src/main/java/org/apache/freemarker/core/debug/RmiDebuggerListenerImpl.java
new file mode 100644
index 0000000..7e263d8
--- /dev/null
+++ b/src/main/java/org/apache/freemarker/core/debug/RmiDebuggerListenerImpl.java
@@ -0,0 +1,67 @@
+/*
+ * 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 org.apache.freemarker.core.debug;
+
+import java.rmi.NoSuchObjectException;
+import java.rmi.RemoteException;
+import java.rmi.server.UnicastRemoteObject;
+import java.rmi.server.Unreferenced;
+
+import org.apache.freemarker.core._CoreLogs;
+import org.apache.freemarker.core.debug.DebuggerClient;
+import org.apache.freemarker.core.debug.DebuggerListener;
+import org.apache.freemarker.core.debug.EnvironmentSuspendedEvent;
+import org.slf4j.Logger;
+
+/**
+ * Used by the {@link DebuggerClient} to create local 
+ */
+class RmiDebuggerListenerImpl
+extends
+    UnicastRemoteObject
+implements
+    DebuggerListener, Unreferenced {
+    
+    private static final Logger LOG = _CoreLogs.DEBUG_CLIENT;
+    
+    private static final long serialVersionUID = 1L;
+
+    private final DebuggerListener listener;
+
+    @Override
+    public void unreferenced() {
+        try {
+            UnicastRemoteObject.unexportObject(this, false);
+        } catch (NoSuchObjectException e) {
+            LOG.warn("Failed to unexport RMI debugger listener", e);
+        }
+    }
+    
+    public RmiDebuggerListenerImpl(DebuggerListener listener) 
+    throws RemoteException {
+        this.listener = listener;
+    }
+
+    @Override
+    public void environmentSuspended(EnvironmentSuspendedEvent e) 
+    throws RemoteException {
+        listener.environmentSuspended(e);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/6939fd07/src/main/java/org/apache/freemarker/core/debug/RmiDebuggerService.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/debug/RmiDebuggerService.java b/src/main/java/org/apache/freemarker/core/debug/RmiDebuggerService.java
new file mode 100644
index 0000000..afa0ec0
--- /dev/null
+++ b/src/main/java/org/apache/freemarker/core/debug/RmiDebuggerService.java
@@ -0,0 +1,307 @@
+/*
+ * 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 org.apache.freemarker.core.debug;
+
+import java.io.Serializable;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+import java.rmi.RemoteException;
+import java.rmi.server.RemoteObject;
+import java.rmi.server.UnicastRemoteObject;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.freemarker.core.Environment;
+import org.apache.freemarker.core.Template;
+import org.apache.freemarker.core._Debug;
+import org.apache.freemarker.core.util.UndeclaredThrowableException;
+
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+
+/**
+ * @version $Id
+ */
+class RmiDebuggerService
+extends
+        _DebuggerService {
+    private final Map templateDebugInfos = new HashMap();
+    private final HashSet suspendedEnvironments = new HashSet();
+    private final Map listeners = new HashMap();
+    private final ReferenceQueue refQueue = new ReferenceQueue();
+     
+
+    private final RmiDebuggerImpl debugger;
+    private DebuggerServer server;
+
+    RmiDebuggerService() {
+        try {
+            debugger = new RmiDebuggerImpl(this);
+            server = new DebuggerServer((Serializable) RemoteObject.toStub(debugger));
+            server.start();
+        } catch (RemoteException e) {
+            e.printStackTrace();
+            throw new UndeclaredThrowableException(e);
+        }
+    }
+    
+    @Override
+    List getBreakpointsSpi(String templateName) {
+        synchronized (templateDebugInfos) {
+            TemplateDebugInfo tdi = findTemplateDebugInfo(templateName);
+            return tdi == null ? Collections.EMPTY_LIST : tdi.breakpoints;
+        }
+    }
+
+    List getBreakpointsSpi() {
+        List sumlist = new ArrayList();
+        synchronized (templateDebugInfos) {
+            for (Iterator iter = templateDebugInfos.values().iterator(); iter.hasNext(); ) {
+                sumlist.addAll(((TemplateDebugInfo) iter.next()).breakpoints);
+            }
+        }
+        Collections.sort(sumlist);
+        return sumlist;
+    }
+
+    // TODO See in SuppressFBWarnings
+    @Override
+    @SuppressFBWarnings(value={ "UW_UNCOND_WAIT", "WA_NOT_IN_LOOP" }, justification="Will have to be re-desigend; postponed.")
+    boolean suspendEnvironmentSpi(Environment env, String templateName, int line)
+    throws RemoteException {
+        RmiDebuggedEnvironmentImpl denv = 
+            (RmiDebuggedEnvironmentImpl)
+                RmiDebuggedEnvironmentImpl.getCachedWrapperFor(env);
+                
+        synchronized (suspendedEnvironments) {
+            suspendedEnvironments.add(denv);
+        }
+        try {
+            EnvironmentSuspendedEvent breakpointEvent = 
+                new EnvironmentSuspendedEvent(this, templateName, line, denv);
+    
+            synchronized (listeners) {
+                for (Iterator iter = listeners.values().iterator(); iter.hasNext(); ) {
+                    DebuggerListener listener = (DebuggerListener) iter.next();
+                    listener.environmentSuspended(breakpointEvent);
+                }
+            }
+            synchronized (denv) {
+                try {
+                    denv.wait();
+                } catch (InterruptedException e) {
+                    // Intentionally ignored
+                }
+            }
+            return denv.isStopped();
+        } finally {
+            synchronized (suspendedEnvironments) {
+                suspendedEnvironments.remove(denv);
+            }
+        }
+    }
+    
+    @Override
+    void registerTemplateSpi(Template template) {
+        String templateName = template.getName();
+        synchronized (templateDebugInfos) {
+            TemplateDebugInfo tdi = createTemplateDebugInfo(templateName);
+            tdi.templates.add(new TemplateReference(templateName, template, refQueue));
+            // Inject already defined breakpoints into the template
+            for (Iterator iter = tdi.breakpoints.iterator(); iter.hasNext(); ) {
+                Breakpoint breakpoint = (Breakpoint) iter.next();
+                _Debug.insertDebugBreak(template, breakpoint.getLine());
+            }
+        }
+    }
+    
+    Collection getSuspendedEnvironments() {
+        return (Collection) suspendedEnvironments.clone();
+    }
+
+    Object addDebuggerListener(DebuggerListener listener) {
+        Object id; 
+        synchronized (listeners) {
+            id = Long.valueOf(System.currentTimeMillis());
+            listeners.put(id, listener);
+        }
+        return id;
+    }
+    
+    void removeDebuggerListener(Object id) {
+        synchronized (listeners) {
+            listeners.remove(id);
+        }
+    }
+
+    void addBreakpoint(Breakpoint breakpoint) {
+        String templateName = breakpoint.getTemplateName();
+        synchronized (templateDebugInfos) {
+            TemplateDebugInfo tdi = createTemplateDebugInfo(templateName);
+            List breakpoints = tdi.breakpoints;
+            int pos = Collections.binarySearch(breakpoints, breakpoint);
+            if (pos < 0) {
+                // Add to the list of breakpoints
+                breakpoints.add(-pos - 1, breakpoint);
+                // Inject the breakpoint into all templates with this name
+                for (Iterator iter = tdi.templates.iterator(); iter.hasNext(); ) {
+                    TemplateReference ref = (TemplateReference) iter.next();
+                    Template t = ref.getTemplate();
+                    if (t == null) {
+                        iter.remove();
+                    } else {
+                        _Debug.insertDebugBreak(t, breakpoint.getLine());
+                    }
+                }
+            }
+        }
+    }
+
+    private TemplateDebugInfo findTemplateDebugInfo(String templateName) {
+        processRefQueue();
+        return (TemplateDebugInfo) templateDebugInfos.get(templateName); 
+    }
+    
+    private TemplateDebugInfo createTemplateDebugInfo(String templateName) {
+        TemplateDebugInfo tdi = findTemplateDebugInfo(templateName);
+        if (tdi == null) {
+            tdi = new TemplateDebugInfo();
+            templateDebugInfos.put(templateName, tdi);
+        }
+        return tdi;
+    }
+    
+    void removeBreakpoint(Breakpoint breakpoint) {
+        String templateName = breakpoint.getTemplateName();
+        synchronized (templateDebugInfos) {
+            TemplateDebugInfo tdi = findTemplateDebugInfo(templateName);
+            if (tdi != null) {
+                List breakpoints = tdi.breakpoints;
+                int pos = Collections.binarySearch(breakpoints, breakpoint);
+                if (pos >= 0) { 
+                    breakpoints.remove(pos);
+                    for (Iterator iter = tdi.templates.iterator(); iter.hasNext(); ) {
+                        TemplateReference ref = (TemplateReference) iter.next();
+                        Template t = ref.getTemplate();
+                        if (t == null) {
+                            iter.remove();
+                        } else {
+                            _Debug.removeDebugBreak(t, breakpoint.getLine());
+                        }
+                    }
+                }
+                if (tdi.isEmpty()) {
+                    templateDebugInfos.remove(templateName);
+                }
+            }
+        }
+    }
+
+    void removeBreakpoints(String templateName) {
+        synchronized (templateDebugInfos) {
+            TemplateDebugInfo tdi = findTemplateDebugInfo(templateName);
+            if (tdi != null) {
+                removeBreakpoints(tdi);
+                if (tdi.isEmpty()) {
+                    templateDebugInfos.remove(templateName);
+                }
+            }
+        }
+    }
+
+    void removeBreakpoints() {
+        synchronized (templateDebugInfos) {
+            for (Iterator iter = templateDebugInfos.values().iterator(); iter.hasNext(); ) {
+                TemplateDebugInfo tdi = (TemplateDebugInfo) iter.next(); 
+                removeBreakpoints(tdi);
+                if (tdi.isEmpty()) {
+                    iter.remove();
+                }
+            }
+        }
+    }
+
+    private void removeBreakpoints(TemplateDebugInfo tdi) {
+        tdi.breakpoints.clear();
+        for (Iterator iter = tdi.templates.iterator(); iter.hasNext(); ) {
+            TemplateReference ref = (TemplateReference) iter.next();
+            Template t = ref.getTemplate();
+            if (t == null) {
+                iter.remove();
+            } else {
+                _Debug.removeDebugBreaks(t);
+            }
+        }
+    }
+
+    private static final class TemplateDebugInfo {
+        final List templates = new ArrayList();
+        final List breakpoints = new ArrayList();
+        
+        boolean isEmpty() {
+            return templates.isEmpty() && breakpoints.isEmpty();
+        }
+    }
+    
+    private static final class TemplateReference extends WeakReference {
+        final String templateName;
+         
+        TemplateReference(String templateName, Template template, ReferenceQueue queue) {
+            super(template, queue);
+            this.templateName = templateName;
+        }
+        
+        Template getTemplate() {
+            return (Template) get();
+        }
+    }
+    
+    private void processRefQueue() {
+        for (; ; ) {
+            TemplateReference ref = (TemplateReference) refQueue.poll();
+            if (ref == null) {
+                break;
+            }
+            TemplateDebugInfo tdi = findTemplateDebugInfo(ref.templateName);
+            if (tdi != null) {
+                tdi.templates.remove(ref);
+                if (tdi.isEmpty()) {
+                    templateDebugInfos.remove(ref.templateName);
+                }
+            }
+        }
+    }
+
+    @Override
+    void shutdownSpi() {
+        server.stop();
+        try {
+            UnicastRemoteObject.unexportObject(debugger, true);
+        } catch (Exception e) {
+        }
+
+        RmiDebuggedEnvironmentImpl.cleanup();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/6939fd07/src/main/java/org/apache/freemarker/core/debug/SoftCache.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/debug/SoftCache.java b/src/main/java/org/apache/freemarker/core/debug/SoftCache.java
new file mode 100644
index 0000000..730574a
--- /dev/null
+++ b/src/main/java/org/apache/freemarker/core/debug/SoftCache.java
@@ -0,0 +1,89 @@
+/*
+ * 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 org.apache.freemarker.core.debug;
+
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.SoftReference;
+import java.util.Map;
+
+class SoftCache {
+    
+    private final ReferenceQueue queue = new ReferenceQueue();
+    private final Map map;
+    
+    public SoftCache(Map backingMap) {
+        map = backingMap;
+    }
+    
+    public Object get(Object key) {
+        processQueue();
+        Reference ref = (Reference) map.get(key);
+        return ref == null ? null : ref.get();
+    }
+
+    public void put(Object key, Object value) {
+        processQueue();
+        map.put(key, new SoftValueReference(key, value, queue));
+    }
+
+    public void remove(Object key) {
+        processQueue();
+        map.remove(key);
+    }
+
+    public void clear() {
+        map.clear();
+        processQueue();
+    }
+    
+    /**
+     * Returns a close approximation of the number of cache entries.
+     */
+    public int getSize() {
+        processQueue();
+        return map.size();
+    }
+
+    private void processQueue() {
+        for (; ; ) {
+            SoftValueReference ref = (SoftValueReference) queue.poll();
+            if (ref == null) {
+                return;
+            }
+            Object key = ref.getKey();
+            map.remove(key);
+        }
+    }
+
+    private static final class SoftValueReference extends SoftReference {
+        private final Object key;
+
+        SoftValueReference(Object key, Object value, ReferenceQueue queue) {
+            super(value, queue);
+            this.key = key;
+        }
+
+        Object getKey() {
+            return key;
+        }
+    }
+    
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/6939fd07/src/main/java/org/apache/freemarker/core/debug/_DebuggerService.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/debug/_DebuggerService.java b/src/main/java/org/apache/freemarker/core/debug/_DebuggerService.java
new file mode 100644
index 0000000..37d094c
--- /dev/null
+++ b/src/main/java/org/apache/freemarker/core/debug/_DebuggerService.java
@@ -0,0 +1,93 @@
+/*
+ * 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 org.apache.freemarker.core.debug;
+
+import java.rmi.RemoteException;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.freemarker.core.Environment;
+import org.apache.freemarker.core.Template;
+import org.apache.freemarker.core.util._SecurityUtil;
+
+/**
+ * Don't use this; used internally by FreeMarker, might changes without notice.
+ * This class provides debugging hooks for the core FreeMarker engine. It is
+ * not usable for anyone outside the FreeMarker core classes.
+ */
+public abstract class _DebuggerService {
+    private static final _DebuggerService INSTANCE = createInstance();
+    
+    private static _DebuggerService createInstance() {
+        // Creates the appropriate service class. If the debugging is turned
+        // off, this is a fast no-op service, otherwise it's the real-thing
+        // RMI service.
+        return 
+            _SecurityUtil.getSystemProperty("org.apache.freemarker.core.debug.password", null) == null
+            ? new NoOpDebuggerService()
+            : new RmiDebuggerService();
+    }
+
+    public static List getBreakpoints(String templateName) {
+        return INSTANCE.getBreakpointsSpi(templateName);
+    }
+    
+    abstract List getBreakpointsSpi(String templateName);
+
+    public static void registerTemplate(Template template) {
+        INSTANCE.registerTemplateSpi(template);
+    }
+    
+    abstract void registerTemplateSpi(Template template);
+    
+    public static boolean suspendEnvironment(Environment env, String templateName, int line)
+    throws RemoteException {
+        return INSTANCE.suspendEnvironmentSpi(env, templateName, line);
+    }
+    
+    abstract boolean suspendEnvironmentSpi(Environment env, String templateName, int line)
+    throws RemoteException;
+
+    abstract void shutdownSpi();
+
+    public static void shutdown() {
+        INSTANCE.shutdownSpi();
+    }
+
+    private static class NoOpDebuggerService extends _DebuggerService {
+        @Override
+        List getBreakpointsSpi(String templateName) {
+            return Collections.EMPTY_LIST;
+        }
+        
+        @Override
+        boolean suspendEnvironmentSpi(Environment env, String templateName, int line) {
+            throw new UnsupportedOperationException();
+        }
+        
+        @Override
+        void registerTemplateSpi(Template template) {
+        }
+
+        @Override
+        void shutdownSpi() {
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/6939fd07/src/main/java/org/apache/freemarker/core/debug/impl/DebuggerServer.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/debug/impl/DebuggerServer.java b/src/main/java/org/apache/freemarker/core/debug/impl/DebuggerServer.java
deleted file mode 100644
index d664695..0000000
--- a/src/main/java/org/apache/freemarker/core/debug/impl/DebuggerServer.java
+++ /dev/null
@@ -1,130 +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 org.apache.freemarker.core.debug.impl;
-
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
-import java.io.UnsupportedEncodingException;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.security.MessageDigest;
-import java.security.SecureRandom;
-import java.util.Arrays;
-import java.util.Random;
-
-import org.apache.freemarker.core._CoreLogs;
-import org.apache.freemarker.core.debug.Debugger;
-import org.apache.freemarker.core.util.UndeclaredThrowableException;
-import org.apache.freemarker.core.util._SecurityUtil;
-import org.slf4j.Logger;
-
-/**
- */
-class DebuggerServer {
-    
-    private static final Logger LOG = _CoreLogs.DEBUG_SERVER;
-    
-    // TODO: Eventually replace with Yarrow    
-    // TODO: Can be extremely slow (on Linux, not enough entropy)
-    private static final Random R = new SecureRandom();
-    
-    private final byte[] password;
-    private final int port;
-    private final Serializable debuggerStub;
-    private boolean stop = false;
-    private ServerSocket serverSocket;
-    
-    public DebuggerServer(Serializable debuggerStub) {
-        port = _SecurityUtil.getSystemProperty("org.apache.freemarker.core.debug.port", Debugger.DEFAULT_PORT).intValue();
-        try {
-            password = _SecurityUtil.getSystemProperty("org.apache.freemarker.core.debug.password", "").getBytes("UTF-8");
-        } catch (UnsupportedEncodingException e) {
-            throw new UndeclaredThrowableException(e);
-        }
-        this.debuggerStub = debuggerStub;
-    }
-    
-    public void start() {
-        new Thread(new Runnable()
-        {
-            @Override
-            public void run() {
-                startInternal();
-            }
-        }, "FreeMarker Debugger Server Acceptor").start();
-    }
-    
-    private void startInternal() {
-        try {
-            serverSocket = new ServerSocket(port);
-            while (!stop) {
-                Socket s = serverSocket.accept();
-                new Thread(new DebuggerAuthProtocol(s)).start();
-            }
-        } catch (IOException e) {
-            LOG.error("Debugger server shut down.", e);
-        }
-    }
-    
-    private class DebuggerAuthProtocol implements Runnable {
-        private final Socket s;
-        
-        DebuggerAuthProtocol(Socket s) {
-            this.s = s;
-        }
-        
-        @Override
-        public void run() {
-            try {
-                ObjectOutputStream out = new ObjectOutputStream(s.getOutputStream());
-                ObjectInputStream in = new ObjectInputStream(s.getInputStream());
-                byte[] challenge = new byte[512];
-                R.nextBytes(challenge);
-                out.writeInt(220); // protocol version
-                out.writeObject(challenge);
-                MessageDigest md = MessageDigest.getInstance("SHA");
-                md.update(password);
-                md.update(challenge);
-                byte[] response = (byte[]) in.readObject();
-                if (Arrays.equals(response, md.digest())) {
-                    out.writeObject(debuggerStub);
-                } else {
-                    out.writeObject(null);
-                }
-            } catch (Exception e) {
-                LOG.warn("Connection to {} abruply broke", s.getInetAddress().getHostAddress(), e);
-            }
-        }
-
-    }
-
-    public void stop() {
-        stop = true;
-        if (serverSocket != null) {
-            try {
-                serverSocket.close();
-            } catch (IOException e) {
-                LOG.error("Unable to close server socket.", e);
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/6939fd07/src/main/java/org/apache/freemarker/core/debug/impl/DebuggerService.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/debug/impl/DebuggerService.java b/src/main/java/org/apache/freemarker/core/debug/impl/DebuggerService.java
deleted file mode 100644
index 65ccb27..0000000
--- a/src/main/java/org/apache/freemarker/core/debug/impl/DebuggerService.java
+++ /dev/null
@@ -1,93 +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 org.apache.freemarker.core.debug.impl;
-
-import java.rmi.RemoteException;
-import java.util.Collections;
-import java.util.List;
-
-import org.apache.freemarker.core.Environment;
-import org.apache.freemarker.core.Template;
-import org.apache.freemarker.core.util._SecurityUtil;
-
-/**
- * This class provides debugging hooks for the core FreeMarker engine. It is
- * not usable for anyone outside the FreeMarker core classes. It is public only
- * as an implementation detail.
- */
-public abstract class DebuggerService {
-    private static final DebuggerService instance = createInstance();
-    
-    private static DebuggerService createInstance() {
-        // Creates the appropriate service class. If the debugging is turned
-        // off, this is a fast no-op service, otherwise it's the real-thing
-        // RMI service.
-        return 
-            _SecurityUtil.getSystemProperty("org.apache.freemarker.core.debug.password", null) == null
-            ? new NoOpDebuggerService()
-            : new RmiDebuggerService();
-    }
-
-    public static List getBreakpoints(String templateName) {
-        return instance.getBreakpointsSpi(templateName);
-    }
-    
-    abstract List getBreakpointsSpi(String templateName);
-
-    public static void registerTemplate(Template template) {
-        instance.registerTemplateSpi(template);
-    }
-    
-    abstract void registerTemplateSpi(Template template);
-    
-    public static boolean suspendEnvironment(Environment env, String templateName, int line)
-    throws RemoteException {
-        return instance.suspendEnvironmentSpi(env, templateName, line);
-    }
-    
-    abstract boolean suspendEnvironmentSpi(Environment env, String templateName, int line)
-    throws RemoteException;
-
-    abstract void shutdownSpi();
-
-    public static void shutdown() {
-        instance.shutdownSpi();
-    }
-
-    private static class NoOpDebuggerService extends DebuggerService {
-        @Override
-        List getBreakpointsSpi(String templateName) {
-            return Collections.EMPTY_LIST;
-        }
-        
-        @Override
-        boolean suspendEnvironmentSpi(Environment env, String templateName, int line) {
-            throw new UnsupportedOperationException();
-        }
-        
-        @Override
-        void registerTemplateSpi(Template template) {
-        }
-
-        @Override
-        void shutdownSpi() {
-        }
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/6939fd07/src/main/java/org/apache/freemarker/core/debug/impl/RmiDebugModelImpl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/debug/impl/RmiDebugModelImpl.java b/src/main/java/org/apache/freemarker/core/debug/impl/RmiDebugModelImpl.java
deleted file mode 100644
index 97da734..0000000
--- a/src/main/java/org/apache/freemarker/core/debug/impl/RmiDebugModelImpl.java
+++ /dev/null
@@ -1,165 +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 org.apache.freemarker.core.debug.impl;
-
-import java.rmi.RemoteException;
-import java.rmi.server.UnicastRemoteObject;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-
-import org.apache.freemarker.core.debug.DebugModel;
-import org.apache.freemarker.core.model.TemplateBooleanModel;
-import org.apache.freemarker.core.model.TemplateCollectionModel;
-import org.apache.freemarker.core.model.TemplateDateModel;
-import org.apache.freemarker.core.model.TemplateHashModel;
-import org.apache.freemarker.core.model.TemplateHashModelEx;
-import org.apache.freemarker.core.model.TemplateMethodModel;
-import org.apache.freemarker.core.model.TemplateMethodModelEx;
-import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.apache.freemarker.core.model.TemplateModelIterator;
-import org.apache.freemarker.core.model.TemplateNumberModel;
-import org.apache.freemarker.core.model.TemplateScalarModel;
-import org.apache.freemarker.core.model.TemplateSequenceModel;
-import org.apache.freemarker.core.model.TemplateTransformModel;
-
-/**
- */
-class RmiDebugModelImpl extends UnicastRemoteObject implements DebugModel {
-    private static final long serialVersionUID = 1L;
-
-    private final TemplateModel model;
-    private final int type;
-    
-    RmiDebugModelImpl(TemplateModel model, int extraTypes) throws RemoteException {
-        super();
-        this.model = model;
-        type = calculateType(model) + extraTypes;
-    }
-
-    private static DebugModel getDebugModel(TemplateModel tm) throws RemoteException {
-        return (DebugModel) RmiDebuggedEnvironmentImpl.getCachedWrapperFor(tm);
-    }
-    @Override
-    public String getAsString() throws TemplateModelException {
-        return ((TemplateScalarModel) model).getAsString();
-    }
-
-    @Override
-    public Number getAsNumber() throws TemplateModelException {
-        return ((TemplateNumberModel) model).getAsNumber();
-    }
-
-    @Override
-    public Date getAsDate() throws TemplateModelException {
-        return ((TemplateDateModel) model).getAsDate();
-    }
-
-    @Override
-    public int getDateType() {
-        return ((TemplateDateModel) model).getDateType();
-    }
-
-    @Override
-    public boolean getAsBoolean() throws TemplateModelException {
-        return ((TemplateBooleanModel) model).getAsBoolean();
-    }
-
-    @Override
-    public int size() throws TemplateModelException {
-        if (model instanceof TemplateSequenceModel) {
-            return ((TemplateSequenceModel) model).size();
-        }
-        return ((TemplateHashModelEx) model).size();
-    }
-
-    @Override
-    public DebugModel get(int index) throws TemplateModelException, RemoteException {
-        return getDebugModel(((TemplateSequenceModel) model).get(index));
-    }
-    
-    @Override
-    public DebugModel[] get(int fromIndex, int toIndex) throws TemplateModelException, RemoteException {
-        DebugModel[] dm = new DebugModel[toIndex - fromIndex];
-        TemplateSequenceModel s = (TemplateSequenceModel) model;
-        for (int i = fromIndex; i < toIndex; i++) {
-            dm[i - fromIndex] = getDebugModel(s.get(i));
-        }
-        return dm;
-    }
-
-    @Override
-    public DebugModel[] getCollection() throws TemplateModelException, RemoteException {
-        List list = new ArrayList();
-        TemplateModelIterator i = ((TemplateCollectionModel) model).iterator();
-        while (i.hasNext()) {
-            list.add(getDebugModel(i.next()));
-        }
-        return (DebugModel[]) list.toArray(new DebugModel[list.size()]);
-    }
-    
-    @Override
-    public DebugModel get(String key) throws TemplateModelException, RemoteException {
-        return getDebugModel(((TemplateHashModel) model).get(key));
-    }
-    
-    @Override
-    public DebugModel[] get(String[] keys) throws TemplateModelException, RemoteException {
-        DebugModel[] dm = new DebugModel[keys.length];
-        TemplateHashModel h = (TemplateHashModel) model;
-        for (int i = 0; i < keys.length; i++) {
-            dm[i] = getDebugModel(h.get(keys[i]));
-        }
-        return dm;
-    }
-
-    @Override
-    public String[] keys() throws TemplateModelException {
-        TemplateHashModelEx h = (TemplateHashModelEx) model;
-        List list = new ArrayList();
-        TemplateModelIterator i = h.keys().iterator();
-        while (i.hasNext()) {
-            list.add(((TemplateScalarModel) i.next()).getAsString());
-        }
-        return (String[]) list.toArray(new String[list.size()]);
-    }
-
-    @Override
-    public int getModelTypes() {
-        return type;
-    }
-    
-    private static int calculateType(TemplateModel model) {
-        int type = 0;
-        if (model instanceof TemplateScalarModel) type += TYPE_SCALAR;
-        if (model instanceof TemplateNumberModel) type += TYPE_NUMBER;
-        if (model instanceof TemplateDateModel) type += TYPE_DATE;
-        if (model instanceof TemplateBooleanModel) type += TYPE_BOOLEAN;
-        if (model instanceof TemplateSequenceModel) type += TYPE_SEQUENCE;
-        if (model instanceof TemplateCollectionModel) type += TYPE_COLLECTION;
-        if (model instanceof TemplateHashModelEx) type += TYPE_HASH_EX;
-        else if (model instanceof TemplateHashModel) type += TYPE_HASH;
-        if (model instanceof TemplateMethodModelEx) type += TYPE_METHOD_EX;
-        else if (model instanceof TemplateMethodModel) type += TYPE_METHOD;
-        if (model instanceof TemplateTransformModel) type += TYPE_TRANSFORM;
-        return type;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/6939fd07/src/main/java/org/apache/freemarker/core/debug/impl/RmiDebuggedEnvironmentImpl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/debug/impl/RmiDebuggedEnvironmentImpl.java b/src/main/java/org/apache/freemarker/core/debug/impl/RmiDebuggedEnvironmentImpl.java
deleted file mode 100644
index eb89830..0000000
--- a/src/main/java/org/apache/freemarker/core/debug/impl/RmiDebuggedEnvironmentImpl.java
+++ /dev/null
@@ -1,337 +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 org.apache.freemarker.core.debug.impl;
-
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-import java.rmi.server.UnicastRemoteObject;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.IdentityHashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-import org.apache.freemarker.core.Configurable;
-import org.apache.freemarker.core.Configuration;
-import org.apache.freemarker.core.Environment;
-import org.apache.freemarker.core.Template;
-import org.apache.freemarker.core.debug.DebugModel;
-import org.apache.freemarker.core.debug.DebuggedEnvironment;
-import org.apache.freemarker.core.model.TemplateCollectionModel;
-import org.apache.freemarker.core.model.TemplateHashModelEx;
-import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.apache.freemarker.core.model.impl.SimpleCollection;
-import org.apache.freemarker.core.model.impl.SimpleScalar;
-import org.apache.freemarker.core.util.UndeclaredThrowableException;
-
-import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
-
-@SuppressWarnings("serial")
-class RmiDebuggedEnvironmentImpl extends RmiDebugModelImpl implements DebuggedEnvironment {
-
-    private static final SoftCache CACHE = new SoftCache(new IdentityHashMap());
-    private static final Object ID_LOCK = new Object();
-    
-    private static long nextId = 1;
-    private static Set remotes = new HashSet();
-
-    
-    private boolean stopped = false;
-    private final long id;
-    
-    private RmiDebuggedEnvironmentImpl(Environment env) throws RemoteException {
-        super(new DebugEnvironmentModel(env), DebugModel.TYPE_ENVIRONMENT);
-        synchronized (ID_LOCK) {
-            id = nextId++;
-        }
-    }
-
-    static synchronized Object getCachedWrapperFor(Object key)
-    throws RemoteException {
-        Object value = CACHE.get(key);
-        if (value == null) {
-            if (key instanceof TemplateModel) {
-                int extraTypes;
-                if (key instanceof DebugConfigurationModel) {
-                    extraTypes = DebugModel.TYPE_CONFIGURATION;
-                } else if (key instanceof DebugTemplateModel) {
-                    extraTypes = DebugModel.TYPE_TEMPLATE;
-                } else {
-                    extraTypes = 0;
-                }
-                value = new RmiDebugModelImpl((TemplateModel) key, extraTypes);
-            } else if (key instanceof Environment) {
-                value = new RmiDebuggedEnvironmentImpl((Environment) key); 
-            } else if (key instanceof Template) {
-                value = new DebugTemplateModel((Template) key);
-            } else if (key instanceof Configuration) {
-                value = new DebugConfigurationModel((Configuration) key);
-            }
-        }
-        if (value != null) {
-            CACHE.put(key, value);
-        }
-        if (value instanceof Remote) {
-            remotes.add(value);
-        }
-        return value;
-    }
-
-    // TODO See in SuppressFBWarnings
-    @Override
-    @SuppressFBWarnings(value="NN_NAKED_NOTIFY", justification="Will have to be re-desigend; postponed.")
-    public void resume() {
-        synchronized (this) {
-            notify();
-        }
-    }
-
-    @Override
-    public void stop() {
-        stopped = true;
-        resume();
-    }
-
-    @Override
-    public long getId() {
-        return id;
-    }
-    
-    boolean isStopped() {
-        return stopped;
-    }
-    
-    private abstract static class DebugMapModel implements TemplateHashModelEx {
-        @Override
-        public int size() {
-            return keySet().size();
-        }
-
-        @Override
-        public TemplateCollectionModel keys() {
-            return new SimpleCollection(keySet());
-        }
-
-        @Override
-        public TemplateCollectionModel values() throws TemplateModelException {
-            Collection keys = keySet();
-            List list = new ArrayList(keys.size());
-            
-            for (Iterator it = keys.iterator(); it.hasNext(); ) {
-                list.add(get((String) it.next()));
-            }
-            return new SimpleCollection(list);
-        }
-
-        @Override
-        public boolean isEmpty() {
-            return size() == 0;
-        }
-        
-        abstract Collection keySet();
-
-        static List composeList(Collection c1, Collection c2) {
-            List list = new ArrayList(c1);
-            list.addAll(c2);
-            Collections.sort(list);
-            return list;
-        }
-    }
-    
-    private static class DebugConfigurableModel extends DebugMapModel {
-        static final List KEYS = Arrays.asList(
-                Configurable.ARITHMETIC_ENGINE_KEY,
-                Configurable.BOOLEAN_FORMAT_KEY,
-                Configurable.LOCALE_KEY,
-                Configurable.NUMBER_FORMAT_KEY,
-                Configurable.OBJECT_WRAPPER_KEY,
-                Configurable.TEMPLATE_EXCEPTION_HANDLER_KEY);
-
-        final Configurable configurable;
-        
-        DebugConfigurableModel(Configurable configurable) {
-            this.configurable = configurable;
-        }
-        
-        @Override
-        Collection keySet() {
-            return KEYS;
-        }
-        
-        @Override
-        public TemplateModel get(String key) throws TemplateModelException {
-            return null; // TODO
-        }
-
-    }
-    
-    private static class DebugConfigurationModel extends DebugConfigurableModel {
-        private static final List KEYS = composeList(DebugConfigurableModel.KEYS, Collections.singleton("sharedVariables"));
-
-        private TemplateModel sharedVariables = new DebugMapModel()
-        {
-            @Override
-            Collection keySet() {
-                return ((Configuration) configurable).getSharedVariableNames();
-            }
-        
-            @Override
-            public TemplateModel get(String key) {
-                return ((Configuration) configurable).getSharedVariable(key);
-            }
-        };
-        
-        DebugConfigurationModel(Configuration config) {
-            super(config);
-        }
-        
-        @Override
-        Collection keySet() {
-            return KEYS;
-        }
-
-        @Override
-        public TemplateModel get(String key) throws TemplateModelException {
-            if ("sharedVariables".equals(key)) {
-                return sharedVariables; 
-            } else {
-                return super.get(key);
-            }
-        }
-    }
-    
-    private static class DebugTemplateModel extends DebugConfigurableModel {
-        private static final List KEYS = composeList(DebugConfigurableModel.KEYS, 
-            Arrays.asList("configuration", "name"));
-    
-        private final SimpleScalar name;
-
-        DebugTemplateModel(Template template) {
-            super(template);
-            name = new SimpleScalar(template.getName());
-        }
-
-        @Override
-        Collection keySet() {
-            return KEYS;
-        }
-
-        @Override
-        public TemplateModel get(String key) throws TemplateModelException {
-            if ("configuration".equals(key)) {
-                try {
-                    return (TemplateModel) getCachedWrapperFor(((Template) configurable).getConfiguration());
-                } catch (RemoteException e) {
-                    throw new TemplateModelException(e);
-                }
-            }
-            if ("name".equals(key)) {
-                return name;
-            }
-            return super.get(key);
-        }
-    }
-
-    private static class DebugEnvironmentModel extends DebugConfigurableModel {
-        private static final List KEYS = composeList(DebugConfigurableModel.KEYS, 
-            Arrays.asList(
-                    "currentNamespace",
-                    "dataModel",
-                    "globalNamespace",
-                    "knownVariables",
-                    "mainNamespace",
-                    "template"));
-    
-        private TemplateModel knownVariables = new DebugMapModel()
-        {
-            @Override
-            Collection keySet() {
-                try {
-                    return ((Environment) configurable).getKnownVariableNames();
-                } catch (TemplateModelException e) {
-                    throw new UndeclaredThrowableException(e);
-                }
-            }
-        
-            @Override
-            public TemplateModel get(String key) throws TemplateModelException {
-                return ((Environment) configurable).getVariable(key);
-            }
-        };
-         
-        DebugEnvironmentModel(Environment env) {
-            super(env);
-        }
-
-        @Override
-        Collection keySet() {
-            return KEYS;
-        }
-
-        @Override
-        public TemplateModel get(String key) throws TemplateModelException {
-            if ("currentNamespace".equals(key)) {
-                return ((Environment) configurable).getCurrentNamespace();
-            }
-            if ("dataModel".equals(key)) {
-                return ((Environment) configurable).getDataModel();
-            }
-            if ("globalNamespace".equals(key)) {
-                return ((Environment) configurable).getGlobalNamespace();
-            }
-            if ("knownVariables".equals(key)) {
-                return knownVariables;
-            }
-            if ("mainNamespace".equals(key)) {
-                return ((Environment) configurable).getMainNamespace();
-            }
-            if ("mainTemplate".equals(key)) {
-                try {
-                    return (TemplateModel) getCachedWrapperFor(((Environment) configurable).getMainTemplate());
-                } catch (RemoteException e) {
-                    throw new TemplateModelException(e);
-                }
-            }
-            if ("currentTemplate".equals(key)) {
-                try {
-                    return (TemplateModel) getCachedWrapperFor(((Environment) configurable).getCurrentTemplate());
-                } catch (RemoteException e) {
-                    throw new TemplateModelException(e);
-                }
-            }
-            return super.get(key);
-        }
-    }
-
-    public static void cleanup() {
-        for (Iterator i = remotes.iterator(); i.hasNext(); ) {
-            Object remoteObject = i.next();
-            try {
-                UnicastRemoteObject.unexportObject((Remote) remoteObject, true);
-            } catch (Exception e) {
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/6939fd07/src/main/java/org/apache/freemarker/core/debug/impl/RmiDebuggerImpl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/debug/impl/RmiDebuggerImpl.java b/src/main/java/org/apache/freemarker/core/debug/impl/RmiDebuggerImpl.java
deleted file mode 100644
index 9fcb3a8..0000000
--- a/src/main/java/org/apache/freemarker/core/debug/impl/RmiDebuggerImpl.java
+++ /dev/null
@@ -1,90 +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 org.apache.freemarker.core.debug.impl;
-
-import java.rmi.RemoteException;
-import java.rmi.server.UnicastRemoteObject;
-import java.util.Collection;
-import java.util.List;
-
-import org.apache.freemarker.core.debug.Breakpoint;
-import org.apache.freemarker.core.debug.Debugger;
-import org.apache.freemarker.core.debug.DebuggerListener;
-
-/**
- */
-class RmiDebuggerImpl
-extends
-    UnicastRemoteObject
-implements
-    Debugger {
-    private static final long serialVersionUID = 1L;
-
-    private final RmiDebuggerService service;
-    
-    protected RmiDebuggerImpl(RmiDebuggerService service) throws RemoteException {
-        this.service = service;
-    }
-
-    @Override
-    public void addBreakpoint(Breakpoint breakpoint) {
-        service.addBreakpoint(breakpoint);
-    }
-
-    @Override
-    public Object addDebuggerListener(DebuggerListener listener) {
-        return service.addDebuggerListener(listener);
-    }
-
-    @Override
-    public List getBreakpoints() {
-        return service.getBreakpointsSpi();
-    }
-
-    @Override
-    public List getBreakpoints(String templateName) {
-        return service.getBreakpointsSpi(templateName);
-    }
-
-    @Override
-    public Collection getSuspendedEnvironments() {
-        return service.getSuspendedEnvironments();
-    }
-
-    @Override
-    public void removeBreakpoint(Breakpoint breakpoint) {
-        service.removeBreakpoint(breakpoint);
-    }
-
-    @Override
-    public void removeDebuggerListener(Object id) {
-        service.removeDebuggerListener(id);
-    }
-
-    @Override
-    public void removeBreakpoints() {
-        service.removeBreakpoints();
-    }
-
-    @Override
-    public void removeBreakpoints(String templateName) {
-        service.removeBreakpoints(templateName);
-    }
-}


[2/5] incubator-freemarker git commit: (Source comment)

Posted by dd...@apache.org.
(Source comment)


Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/de1bcf77
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/de1bcf77
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/de1bcf77

Branch: refs/heads/3
Commit: de1bcf779fa22b92a5db9e1272b42184750ffe99
Parents: 92ea6b5
Author: ddekany <dd...@apache.org>
Authored: Wed Mar 1 16:57:45 2017 +0100
Committer: ddekany <dd...@apache.org>
Committed: Wed Mar 1 16:57:45 2017 +0100

----------------------------------------------------------------------
 src/main/java/org/apache/freemarker/core/model/impl/_ModelAPI.java | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/de1bcf77/src/main/java/org/apache/freemarker/core/model/impl/_ModelAPI.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/model/impl/_ModelAPI.java b/src/main/java/org/apache/freemarker/core/model/impl/_ModelAPI.java
index 3e24c65..e5c9624 100644
--- a/src/main/java/org/apache/freemarker/core/model/impl/_ModelAPI.java
+++ b/src/main/java/org/apache/freemarker/core/model/impl/_ModelAPI.java
@@ -132,6 +132,7 @@ public class _ModelAPI {
      * @param dowSubclassFactory Creates a <em>new</em> read-only object wrapper of the desired
      *     {@link DefaultObjectWrapper} subclass. 
      */
+    // [FM3] Unnecessary generalization, unless we publish this API
     public static <OW extends DefaultObjectWrapper, OWC extends DefaultObjectWrapperConfiguration> OW
     getDefaultObjectWrapperSubclassSingleton(
             OWC settings,


[3/5] incubator-freemarker git commit: Updated/added package.html-s.

Posted by dd...@apache.org.
Updated/added package.html-s.


Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/64ca9c24
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/64ca9c24
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/64ca9c24

Branch: refs/heads/3
Commit: 64ca9c24fc42c5ff2cef897ec7d9c94a77adb2d4
Parents: de1bcf77
Author: ddekany <dd...@apache.org>
Authored: Wed Mar 1 19:00:35 2017 +0100
Committer: ddekany <dd...@apache.org>
Committed: Wed Mar 1 19:00:35 2017 +0100

----------------------------------------------------------------------
 .../core/arithmetic/impl/package.html           | 26 ++++++++++++++++++++
 .../freemarker/core/arithmetic/package.html     | 25 +++++++++++++++++++
 .../freemarker/core/model/impl/package.html     | 17 ++-----------
 .../apache/freemarker/core/model/package.html   |  2 +-
 .../core/outputformat/impl/package.html         | 26 ++++++++++++++++++++
 .../freemarker/core/outputformat/package.html   | 25 +++++++++++++++++++
 .../org/apache/freemarker/core/package.html     |  2 +-
 .../core/templateresolver/impl/package.html     | 26 ++++++++++++++++++++
 .../core/templateresolver/package.html          |  2 +-
 .../core/valueformat/impl/package.html          | 26 ++++++++++++++++++++
 .../freemarker/core/valueformat/package.html    | 25 +++++++++++++++++++
 .../java/org/apache/freemarker/dom/package.html |  3 +--
 .../apache/freemarker/servlet/jsp/package.html  |  5 +---
 .../org/apache/freemarker/servlet/package.html  |  3 ++-
 14 files changed, 188 insertions(+), 25 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/64ca9c24/src/main/java/org/apache/freemarker/core/arithmetic/impl/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/arithmetic/impl/package.html b/src/main/java/org/apache/freemarker/core/arithmetic/impl/package.html
new file mode 100644
index 0000000..e093fd6
--- /dev/null
+++ b/src/main/java/org/apache/freemarker/core/arithmetic/impl/package.html
@@ -0,0 +1,26 @@
+<!--
+  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>
+</head>
+<body>
+<p>Arithmetic used in templates: Standard implementations. This package is part of the
+published API, that is, user code can safely depend on it.</p>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/64ca9c24/src/main/java/org/apache/freemarker/core/arithmetic/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/arithmetic/package.html b/src/main/java/org/apache/freemarker/core/arithmetic/package.html
new file mode 100644
index 0000000..18d2c7f
--- /dev/null
+++ b/src/main/java/org/apache/freemarker/core/arithmetic/package.html
@@ -0,0 +1,25 @@
+<!--
+  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>
+</head>
+<body>
+<p>Arithmetic used in templates: Base classes/interfaces.</p>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/64ca9c24/src/main/java/org/apache/freemarker/core/model/impl/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/model/impl/package.html b/src/main/java/org/apache/freemarker/core/model/impl/package.html
index 9c315a4..b3db746 100644
--- a/src/main/java/org/apache/freemarker/core/model/impl/package.html
+++ b/src/main/java/org/apache/freemarker/core/model/impl/package.html
@@ -18,22 +18,9 @@
 -->
 <html>
 <head>
-<title></title>
 </head>
 <body>
-
-<p>The {@linkplain org.apache.freemarker.core.model.impl.DefaultObjectWrapper default object wrapper} of FreeMarker uses
-this to expose Java Beans and POJO-s to templates.</p>
-
-<p>Most of the issues dealing with beans are handled by the 
-{@link freemarker.ext.beans.DefaultObjectWrapper#wrap(Object)}and {@link
-freemarker.ext.beans.DefaultObjectWrapper#getStaticModels()} methods. In normal cases,
- these are the only methods
-you should use to turn an arbitrary Java object into a 
-FreeMarker {@link freemarker.template.TemplateModel}. Additionally, you can manually create 
-instance of any wrapper class using its constructors.
-Note, however that in such cases you bypass the eventual model caching
-of the wrapper.</p>
-
+<p>Data model and template language type system: Standard implementations. This package is part of the
+published API, that is, user code can safely depend on it.</p>
 </body>
 </html>

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/64ca9c24/src/main/java/org/apache/freemarker/core/model/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/model/package.html b/src/main/java/org/apache/freemarker/core/model/package.html
index 891509e..a2a9cfe 100644
--- a/src/main/java/org/apache/freemarker/core/model/package.html
+++ b/src/main/java/org/apache/freemarker/core/model/package.html
@@ -20,6 +20,6 @@
 <head>
 </head>
 <body>
-<p>Things related to <tt>TemplateModel</tt>-s (basically the type system of FTL).</p> 
+<p>Data model and template language type system: Base classes/interfaces.</p>
 </body>
 </html>

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/64ca9c24/src/main/java/org/apache/freemarker/core/outputformat/impl/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/outputformat/impl/package.html b/src/main/java/org/apache/freemarker/core/outputformat/impl/package.html
new file mode 100644
index 0000000..2ff5d6d
--- /dev/null
+++ b/src/main/java/org/apache/freemarker/core/outputformat/impl/package.html
@@ -0,0 +1,26 @@
+<!--
+  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>
+</head>
+<body>
+<p>Template output format: Standard implementations. This package is part of the
+published API, that is, user code can safely depend on it.</p>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/64ca9c24/src/main/java/org/apache/freemarker/core/outputformat/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/outputformat/package.html b/src/main/java/org/apache/freemarker/core/outputformat/package.html
new file mode 100644
index 0000000..47bebfe
--- /dev/null
+++ b/src/main/java/org/apache/freemarker/core/outputformat/package.html
@@ -0,0 +1,25 @@
+<!--
+  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>
+</head>
+<body>
+<p>Template output format: Base classes/interfaces</p>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/64ca9c24/src/main/java/org/apache/freemarker/core/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/package.html b/src/main/java/org/apache/freemarker/core/package.html
index 3f622ec..be9dab9 100644
--- a/src/main/java/org/apache/freemarker/core/package.html
+++ b/src/main/java/org/apache/freemarker/core/package.html
@@ -20,7 +20,7 @@
 <head>
 </head>
 <body>
-<p><b>The fundamental, most commonly used API-s of FreeMarker;</b>
+<p><b>The most commonly used API-s of FreeMarker;</b>
 start with {@link freemarker.template.Configuration Configuration} (see also the
 <a href="http://freemarker.org/docs/pgui_quickstart.html" target="_blank">Getting Stared</a> in the Manual.)</p>
 </body>

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/64ca9c24/src/main/java/org/apache/freemarker/core/templateresolver/impl/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/templateresolver/impl/package.html b/src/main/java/org/apache/freemarker/core/templateresolver/impl/package.html
new file mode 100644
index 0000000..8734174
--- /dev/null
+++ b/src/main/java/org/apache/freemarker/core/templateresolver/impl/package.html
@@ -0,0 +1,26 @@
+<!--
+  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>
+</head>
+<body>
+<p>Template lookup, loading and caching: Standard implementations. This package is part of the
+published API, that is, user code can safely depend on it.</p>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/64ca9c24/src/main/java/org/apache/freemarker/core/templateresolver/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/templateresolver/package.html b/src/main/java/org/apache/freemarker/core/templateresolver/package.html
index 9f43949..dd01586 100644
--- a/src/main/java/org/apache/freemarker/core/templateresolver/package.html
+++ b/src/main/java/org/apache/freemarker/core/templateresolver/package.html
@@ -20,6 +20,6 @@
 <head>
 </head>
 <body>
-<p>Template lookup, loading, caching and template naming rules.</p>
+<p>Template lookup, loading, and caching: Base classes/interfaces</p>
 </body>
 </html>

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/64ca9c24/src/main/java/org/apache/freemarker/core/valueformat/impl/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/valueformat/impl/package.html b/src/main/java/org/apache/freemarker/core/valueformat/impl/package.html
new file mode 100644
index 0000000..b776668
--- /dev/null
+++ b/src/main/java/org/apache/freemarker/core/valueformat/impl/package.html
@@ -0,0 +1,26 @@
+<!--
+  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>
+</head>
+<body>
+<p>Formatting values shown in templates: Standard implementations. This package is part of the published API, that
+is, user code can safely depend on it.</p>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/64ca9c24/src/main/java/org/apache/freemarker/core/valueformat/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/valueformat/package.html b/src/main/java/org/apache/freemarker/core/valueformat/package.html
new file mode 100644
index 0000000..bfb8183
--- /dev/null
+++ b/src/main/java/org/apache/freemarker/core/valueformat/package.html
@@ -0,0 +1,25 @@
+<!--
+  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>
+</head>
+<body>
+<p>Formatting values shown in templates: Base classes/interfaces</p>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/64ca9c24/src/main/java/org/apache/freemarker/dom/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/dom/package.html b/src/main/java/org/apache/freemarker/dom/package.html
index d9239e4..61b1737 100644
--- a/src/main/java/org/apache/freemarker/dom/package.html
+++ b/src/main/java/org/apache/freemarker/dom/package.html
@@ -24,8 +24,7 @@
 
 <p>Exposes DOM XML nodes to templates as easily traversable trees;
 see <a href="http://freemarker.org/docs/xgui.html" target="_blank">in the Manual</a>.
-The {@link freemarker.template.DefaultObjectWrapper default object wrapper} of FreeMarker
-automatically wraps W3C nodes with this.
+The default object wrapper of FreeMarker can automatically wraps W3C nodes with this.
 
 </body>
 </html>

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/64ca9c24/src/main/java/org/apache/freemarker/servlet/jsp/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/servlet/jsp/package.html b/src/main/java/org/apache/freemarker/servlet/jsp/package.html
index 6a97480..8d65a1c 100644
--- a/src/main/java/org/apache/freemarker/servlet/jsp/package.html
+++ b/src/main/java/org/apache/freemarker/servlet/jsp/package.html
@@ -21,9 +21,6 @@
 </head>
 <body>
 <p>
-Classes for two-way FreeMarker-JSP integration. It contains both a JSP
-custom tag that allows embedding of FreeMarker templates inside JSP
-pages, as well as the infrastructure that allows JSP custom tags to be
-used inside FreeMarker templates.
+Allows JSP custom tags to be used inside FreeMarker templates as if they where FreeMarker directives.
 </body>
 </html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/64ca9c24/src/main/java/org/apache/freemarker/servlet/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/servlet/package.html b/src/main/java/org/apache/freemarker/servlet/package.html
index 99f7e24..c364bb0 100644
--- a/src/main/java/org/apache/freemarker/servlet/package.html
+++ b/src/main/java/org/apache/freemarker/servlet/package.html
@@ -20,6 +20,7 @@
 <body>
 <p>Servlet for legacy "Model 2" frameworks that allows using FreeMarker
 templates instead of JSP as the MVC View
-(see <a href="http://freemarker.org/docs/pgui_misc_servlet.html" target="_blank">in the Manual</a>).</p>
+(see <a href="http://freemarker.org/docs/pgui_misc_servlet.html" target="_blank">in the Manual</a>), also
+custom JSP tag support.</p>
 </body>
 </html>


[4/5] incubator-freemarker git commit: Moved debug feature into a single package.

Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/6939fd07/src/main/java/org/apache/freemarker/core/debug/impl/RmiDebuggerListenerImpl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/debug/impl/RmiDebuggerListenerImpl.java b/src/main/java/org/apache/freemarker/core/debug/impl/RmiDebuggerListenerImpl.java
deleted file mode 100644
index 4d7b8a7..0000000
--- a/src/main/java/org/apache/freemarker/core/debug/impl/RmiDebuggerListenerImpl.java
+++ /dev/null
@@ -1,67 +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 org.apache.freemarker.core.debug.impl;
-
-import java.rmi.NoSuchObjectException;
-import java.rmi.RemoteException;
-import java.rmi.server.UnicastRemoteObject;
-import java.rmi.server.Unreferenced;
-
-import org.apache.freemarker.core._CoreLogs;
-import org.apache.freemarker.core.debug.DebuggerClient;
-import org.apache.freemarker.core.debug.DebuggerListener;
-import org.apache.freemarker.core.debug.EnvironmentSuspendedEvent;
-import org.slf4j.Logger;
-
-/**
- * Used by the {@link DebuggerClient} to create local 
- */
-public class RmiDebuggerListenerImpl
-extends
-    UnicastRemoteObject
-implements
-    DebuggerListener, Unreferenced {
-    
-    private static final Logger LOG = _CoreLogs.DEBUG_CLIENT;
-    
-    private static final long serialVersionUID = 1L;
-
-    private final DebuggerListener listener;
-
-    @Override
-    public void unreferenced() {
-        try {
-            UnicastRemoteObject.unexportObject(this, false);
-        } catch (NoSuchObjectException e) {
-            LOG.warn("Failed to unexport RMI debugger listener", e);
-        }
-    }
-    
-    public RmiDebuggerListenerImpl(DebuggerListener listener) 
-    throws RemoteException {
-        this.listener = listener;
-    }
-
-    @Override
-    public void environmentSuspended(EnvironmentSuspendedEvent e) 
-    throws RemoteException {
-        listener.environmentSuspended(e);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/6939fd07/src/main/java/org/apache/freemarker/core/debug/impl/RmiDebuggerService.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/debug/impl/RmiDebuggerService.java b/src/main/java/org/apache/freemarker/core/debug/impl/RmiDebuggerService.java
deleted file mode 100644
index 555fc4e..0000000
--- a/src/main/java/org/apache/freemarker/core/debug/impl/RmiDebuggerService.java
+++ /dev/null
@@ -1,310 +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 org.apache.freemarker.core.debug.impl;
-
-import java.io.Serializable;
-import java.lang.ref.ReferenceQueue;
-import java.lang.ref.WeakReference;
-import java.rmi.RemoteException;
-import java.rmi.server.RemoteObject;
-import java.rmi.server.UnicastRemoteObject;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.freemarker.core.Environment;
-import org.apache.freemarker.core.Template;
-import org.apache.freemarker.core._Debug;
-import org.apache.freemarker.core.debug.Breakpoint;
-import org.apache.freemarker.core.debug.DebuggerListener;
-import org.apache.freemarker.core.debug.EnvironmentSuspendedEvent;
-import org.apache.freemarker.core.util.UndeclaredThrowableException;
-
-import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
-
-/**
- * @version $Id
- */
-class RmiDebuggerService
-extends
-    DebuggerService {
-    private final Map templateDebugInfos = new HashMap();
-    private final HashSet suspendedEnvironments = new HashSet();
-    private final Map listeners = new HashMap();
-    private final ReferenceQueue refQueue = new ReferenceQueue();
-     
-
-    private final RmiDebuggerImpl debugger;
-    private DebuggerServer server;
-
-    RmiDebuggerService() {
-        try {
-            debugger = new RmiDebuggerImpl(this);
-            server = new DebuggerServer((Serializable) RemoteObject.toStub(debugger));
-            server.start();
-        } catch (RemoteException e) {
-            e.printStackTrace();
-            throw new UndeclaredThrowableException(e);
-        }
-    }
-    
-    @Override
-    List getBreakpointsSpi(String templateName) {
-        synchronized (templateDebugInfos) {
-            TemplateDebugInfo tdi = findTemplateDebugInfo(templateName);
-            return tdi == null ? Collections.EMPTY_LIST : tdi.breakpoints;
-        }
-    }
-
-    List getBreakpointsSpi() {
-        List sumlist = new ArrayList();
-        synchronized (templateDebugInfos) {
-            for (Iterator iter = templateDebugInfos.values().iterator(); iter.hasNext(); ) {
-                sumlist.addAll(((TemplateDebugInfo) iter.next()).breakpoints);
-            }
-        }
-        Collections.sort(sumlist);
-        return sumlist;
-    }
-
-    // TODO See in SuppressFBWarnings
-    @Override
-    @SuppressFBWarnings(value={ "UW_UNCOND_WAIT", "WA_NOT_IN_LOOP" }, justification="Will have to be re-desigend; postponed.")
-    boolean suspendEnvironmentSpi(Environment env, String templateName, int line)
-    throws RemoteException {
-        RmiDebuggedEnvironmentImpl denv = 
-            (RmiDebuggedEnvironmentImpl)
-                RmiDebuggedEnvironmentImpl.getCachedWrapperFor(env);
-                
-        synchronized (suspendedEnvironments) {
-            suspendedEnvironments.add(denv);
-        }
-        try {
-            EnvironmentSuspendedEvent breakpointEvent = 
-                new EnvironmentSuspendedEvent(this, templateName, line, denv);
-    
-            synchronized (listeners) {
-                for (Iterator iter = listeners.values().iterator(); iter.hasNext(); ) {
-                    DebuggerListener listener = (DebuggerListener) iter.next();
-                    listener.environmentSuspended(breakpointEvent);
-                }
-            }
-            synchronized (denv) {
-                try {
-                    denv.wait();
-                } catch (InterruptedException e) {
-                    // Intentionally ignored
-                }
-            }
-            return denv.isStopped();
-        } finally {
-            synchronized (suspendedEnvironments) {
-                suspendedEnvironments.remove(denv);
-            }
-        }
-    }
-    
-    @Override
-    void registerTemplateSpi(Template template) {
-        String templateName = template.getName();
-        synchronized (templateDebugInfos) {
-            TemplateDebugInfo tdi = createTemplateDebugInfo(templateName);
-            tdi.templates.add(new TemplateReference(templateName, template, refQueue));
-            // Inject already defined breakpoints into the template
-            for (Iterator iter = tdi.breakpoints.iterator(); iter.hasNext(); ) {
-                Breakpoint breakpoint = (Breakpoint) iter.next();
-                _Debug.insertDebugBreak(template, breakpoint.getLine());
-            }
-        }
-    }
-    
-    Collection getSuspendedEnvironments() {
-        return (Collection) suspendedEnvironments.clone();
-    }
-
-    Object addDebuggerListener(DebuggerListener listener) {
-        Object id; 
-        synchronized (listeners) {
-            id = Long.valueOf(System.currentTimeMillis());
-            listeners.put(id, listener);
-        }
-        return id;
-    }
-    
-    void removeDebuggerListener(Object id) {
-        synchronized (listeners) {
-            listeners.remove(id);
-        }
-    }
-
-    void addBreakpoint(Breakpoint breakpoint) {
-        String templateName = breakpoint.getTemplateName();
-        synchronized (templateDebugInfos) {
-            TemplateDebugInfo tdi = createTemplateDebugInfo(templateName);
-            List breakpoints = tdi.breakpoints;
-            int pos = Collections.binarySearch(breakpoints, breakpoint);
-            if (pos < 0) {
-                // Add to the list of breakpoints
-                breakpoints.add(-pos - 1, breakpoint);
-                // Inject the breakpoint into all templates with this name
-                for (Iterator iter = tdi.templates.iterator(); iter.hasNext(); ) {
-                    TemplateReference ref = (TemplateReference) iter.next();
-                    Template t = ref.getTemplate();
-                    if (t == null) {
-                        iter.remove();
-                    } else {
-                        _Debug.insertDebugBreak(t, breakpoint.getLine());
-                    }
-                }
-            }
-        }
-    }
-
-    private TemplateDebugInfo findTemplateDebugInfo(String templateName) {
-        processRefQueue();
-        return (TemplateDebugInfo) templateDebugInfos.get(templateName); 
-    }
-    
-    private TemplateDebugInfo createTemplateDebugInfo(String templateName) {
-        TemplateDebugInfo tdi = findTemplateDebugInfo(templateName);
-        if (tdi == null) {
-            tdi = new TemplateDebugInfo();
-            templateDebugInfos.put(templateName, tdi);
-        }
-        return tdi;
-    }
-    
-    void removeBreakpoint(Breakpoint breakpoint) {
-        String templateName = breakpoint.getTemplateName();
-        synchronized (templateDebugInfos) {
-            TemplateDebugInfo tdi = findTemplateDebugInfo(templateName);
-            if (tdi != null) {
-                List breakpoints = tdi.breakpoints;
-                int pos = Collections.binarySearch(breakpoints, breakpoint);
-                if (pos >= 0) { 
-                    breakpoints.remove(pos);
-                    for (Iterator iter = tdi.templates.iterator(); iter.hasNext(); ) {
-                        TemplateReference ref = (TemplateReference) iter.next();
-                        Template t = ref.getTemplate();
-                        if (t == null) {
-                            iter.remove();
-                        } else {
-                            _Debug.removeDebugBreak(t, breakpoint.getLine());
-                        }
-                    }
-                }
-                if (tdi.isEmpty()) {
-                    templateDebugInfos.remove(templateName);
-                }
-            }
-        }
-    }
-
-    void removeBreakpoints(String templateName) {
-        synchronized (templateDebugInfos) {
-            TemplateDebugInfo tdi = findTemplateDebugInfo(templateName);
-            if (tdi != null) {
-                removeBreakpoints(tdi);
-                if (tdi.isEmpty()) {
-                    templateDebugInfos.remove(templateName);
-                }
-            }
-        }
-    }
-
-    void removeBreakpoints() {
-        synchronized (templateDebugInfos) {
-            for (Iterator iter = templateDebugInfos.values().iterator(); iter.hasNext(); ) {
-                TemplateDebugInfo tdi = (TemplateDebugInfo) iter.next(); 
-                removeBreakpoints(tdi);
-                if (tdi.isEmpty()) {
-                    iter.remove();
-                }
-            }
-        }
-    }
-
-    private void removeBreakpoints(TemplateDebugInfo tdi) {
-        tdi.breakpoints.clear();
-        for (Iterator iter = tdi.templates.iterator(); iter.hasNext(); ) {
-            TemplateReference ref = (TemplateReference) iter.next();
-            Template t = ref.getTemplate();
-            if (t == null) {
-                iter.remove();
-            } else {
-                _Debug.removeDebugBreaks(t);
-            }
-        }
-    }
-
-    private static final class TemplateDebugInfo {
-        final List templates = new ArrayList();
-        final List breakpoints = new ArrayList();
-        
-        boolean isEmpty() {
-            return templates.isEmpty() && breakpoints.isEmpty();
-        }
-    }
-    
-    private static final class TemplateReference extends WeakReference {
-        final String templateName;
-         
-        TemplateReference(String templateName, Template template, ReferenceQueue queue) {
-            super(template, queue);
-            this.templateName = templateName;
-        }
-        
-        Template getTemplate() {
-            return (Template) get();
-        }
-    }
-    
-    private void processRefQueue() {
-        for (; ; ) {
-            TemplateReference ref = (TemplateReference) refQueue.poll();
-            if (ref == null) {
-                break;
-            }
-            TemplateDebugInfo tdi = findTemplateDebugInfo(ref.templateName);
-            if (tdi != null) {
-                tdi.templates.remove(ref);
-                if (tdi.isEmpty()) {
-                    templateDebugInfos.remove(ref.templateName);
-                }
-            }
-        }
-    }
-
-    @Override
-    void shutdownSpi() {
-        server.stop();
-        try {
-            UnicastRemoteObject.unexportObject(debugger, true);
-        } catch (Exception e) {
-        }
-
-        RmiDebuggedEnvironmentImpl.cleanup();
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/6939fd07/src/main/java/org/apache/freemarker/core/debug/impl/SoftCache.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/debug/impl/SoftCache.java b/src/main/java/org/apache/freemarker/core/debug/impl/SoftCache.java
deleted file mode 100644
index bbc1423..0000000
--- a/src/main/java/org/apache/freemarker/core/debug/impl/SoftCache.java
+++ /dev/null
@@ -1,89 +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 org.apache.freemarker.core.debug.impl;
-
-import java.lang.ref.Reference;
-import java.lang.ref.ReferenceQueue;
-import java.lang.ref.SoftReference;
-import java.util.Map;
-
-class SoftCache {
-    
-    private final ReferenceQueue queue = new ReferenceQueue();
-    private final Map map;
-    
-    public SoftCache(Map backingMap) {
-        map = backingMap;
-    }
-    
-    public Object get(Object key) {
-        processQueue();
-        Reference ref = (Reference) map.get(key);
-        return ref == null ? null : ref.get();
-    }
-
-    public void put(Object key, Object value) {
-        processQueue();
-        map.put(key, new SoftValueReference(key, value, queue));
-    }
-
-    public void remove(Object key) {
-        processQueue();
-        map.remove(key);
-    }
-
-    public void clear() {
-        map.clear();
-        processQueue();
-    }
-    
-    /**
-     * Returns a close approximation of the number of cache entries.
-     */
-    public int getSize() {
-        processQueue();
-        return map.size();
-    }
-
-    private void processQueue() {
-        for (; ; ) {
-            SoftValueReference ref = (SoftValueReference) queue.poll();
-            if (ref == null) {
-                return;
-            }
-            Object key = ref.getKey();
-            map.remove(key);
-        }
-    }
-
-    private static final class SoftValueReference extends SoftReference {
-        private final Object key;
-
-        SoftValueReference(Object key, Object value, ReferenceQueue queue) {
-            super(value, queue);
-            this.key = key;
-        }
-
-        Object getKey() {
-            return key;
-        }
-    }
-    
-}
\ No newline at end of file