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 2016/12/03 14:28:09 UTC

incubator-freemarker git commit: (Bit of test code cleanup.)

Repository: incubator-freemarker
Updated Branches:
  refs/heads/2.3-gae cded5be79 -> 5be880de5


(Bit of test code cleanup.)


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

Branch: refs/heads/2.3-gae
Commit: 5be880de56fda5a5650d27376f05e87dc08829be
Parents: cded5be
Author: ddekany <dd...@apache.org>
Authored: Sat Dec 3 15:28:02 2016 +0100
Committer: ddekany <dd...@apache.org>
Committed: Sat Dec 3 15:28:02 2016 +0100

----------------------------------------------------------------------
 src/test/java/freemarker/core/ASTTest.java      |   2 +-
 .../ext/beans/BeansAPINewInstanceTest.java      |   6 +-
 .../ext/beans/BeansWrapperSingletonsTest.java   |   2 +-
 .../template/TemplateLanguageVersionTest.java   |   2 +-
 .../CopyrightCommentRemoverTemplateLoader.java  |   1 +
 src/test/java/freemarker/test/TemplateTest.java |   1 +
 src/test/java/freemarker/test/TestUtil.java     | 126 ---------
 .../freemarker/test/servlet/WebAppTestCase.java |   2 +-
 .../models/OverloadedMethods2.java              | 144 +++++-----
 .../freemarker/test/utility/FileTestCase.java   |   1 -
 .../java/freemarker/test/utility/Helpers.java   | 164 ------------
 .../java/freemarker/test/utility/TestUtil.java  | 266 +++++++++++++++++++
 12 files changed, 347 insertions(+), 370 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/5be880de/src/test/java/freemarker/core/ASTTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/core/ASTTest.java b/src/test/java/freemarker/core/ASTTest.java
index b1e1729..f31b53c 100644
--- a/src/test/java/freemarker/core/ASTTest.java
+++ b/src/test/java/freemarker/core/ASTTest.java
@@ -24,8 +24,8 @@ import java.io.IOException;
 
 import freemarker.core.ASTPrinter.Options;
 import freemarker.template.utility.StringUtil;
-import freemarker.test.TestUtil;
 import freemarker.test.utility.FileTestCase;
+import freemarker.test.utility.TestUtil;
 
 public class ASTTest extends FileTestCase {
 

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/5be880de/src/test/java/freemarker/ext/beans/BeansAPINewInstanceTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/ext/beans/BeansAPINewInstanceTest.java b/src/test/java/freemarker/ext/beans/BeansAPINewInstanceTest.java
index ebc679c..d8e5d3a 100644
--- a/src/test/java/freemarker/ext/beans/BeansAPINewInstanceTest.java
+++ b/src/test/java/freemarker/ext/beans/BeansAPINewInstanceTest.java
@@ -21,7 +21,7 @@ package freemarker.ext.beans;
 
 import junit.framework.TestCase;
 import freemarker.template.Configuration;
-import freemarker.test.utility.Helpers;
+import freemarker.test.utility.TestUtil;
 
 public class BeansAPINewInstanceTest extends TestCase {
 
@@ -110,8 +110,8 @@ public class BeansAPINewInstanceTest extends TestCase {
         public Constructors(Integer x, Integer y) { s = "Integer " + x + ", Integer " + y; }
         public Constructors(Object x, Object y) { s = "Object " + x + ", Object " + y; }
 
-        public Constructors(int... xs) { s = "int... " + Helpers.arrayToString(xs); }
-        public Constructors(Object x, int... ys) { s = "Object " + x + ", int... " + Helpers.arrayToString(ys); }
+        public Constructors(int... xs) { s = "int... " + TestUtil.arrayToString(xs); }
+        public Constructors(Object x, int... ys) { s = "Object " + x + ", int... " + TestUtil.arrayToString(ys); }
         
         @Override
         public String toString() {

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/5be880de/src/test/java/freemarker/ext/beans/BeansWrapperSingletonsTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/ext/beans/BeansWrapperSingletonsTest.java b/src/test/java/freemarker/ext/beans/BeansWrapperSingletonsTest.java
index d4f762f..9eedd53 100644
--- a/src/test/java/freemarker/ext/beans/BeansWrapperSingletonsTest.java
+++ b/src/test/java/freemarker/ext/beans/BeansWrapperSingletonsTest.java
@@ -39,7 +39,7 @@ import freemarker.template.TemplateModelException;
 import freemarker.template.TemplateScalarModel;
 import freemarker.template.Version;
 import freemarker.template._TemplateAPI;
-import freemarker.test.TestUtil;
+import freemarker.test.utility.TestUtil;
 import junit.framework.TestCase;
 
 public class BeansWrapperSingletonsTest extends TestCase {

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/5be880de/src/test/java/freemarker/template/TemplateLanguageVersionTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/template/TemplateLanguageVersionTest.java b/src/test/java/freemarker/template/TemplateLanguageVersionTest.java
index 7d60c30..490c3c0 100644
--- a/src/test/java/freemarker/template/TemplateLanguageVersionTest.java
+++ b/src/test/java/freemarker/template/TemplateLanguageVersionTest.java
@@ -27,7 +27,7 @@ import java.io.IOException;
 import org.junit.Test;
 
 import freemarker.cache.StringTemplateLoader;
-import freemarker.test.TestUtil;
+import freemarker.test.utility.TestUtil;
 public class TemplateLanguageVersionTest {
 
     @Test

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/5be880de/src/test/java/freemarker/test/CopyrightCommentRemoverTemplateLoader.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/test/CopyrightCommentRemoverTemplateLoader.java b/src/test/java/freemarker/test/CopyrightCommentRemoverTemplateLoader.java
index 0b5ca05..8c4a48d 100644
--- a/src/test/java/freemarker/test/CopyrightCommentRemoverTemplateLoader.java
+++ b/src/test/java/freemarker/test/CopyrightCommentRemoverTemplateLoader.java
@@ -25,6 +25,7 @@ import java.io.StringReader;
 import org.apache.commons.io.IOUtils;
 
 import freemarker.cache.TemplateLoader;
+import freemarker.test.utility.TestUtil;
 
 public class CopyrightCommentRemoverTemplateLoader implements TemplateLoader {
 

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/5be880de/src/test/java/freemarker/test/TemplateTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/test/TemplateTest.java b/src/test/java/freemarker/test/TemplateTest.java
index c4d4e59..5a1cdec 100644
--- a/src/test/java/freemarker/test/TemplateTest.java
+++ b/src/test/java/freemarker/test/TemplateTest.java
@@ -42,6 +42,7 @@ import freemarker.template.Template;
 import freemarker.template.TemplateException;
 import freemarker.template.utility.StringUtil;
 import freemarker.test.templatesuite.TemplateTestSuite;
+import freemarker.test.utility.TestUtil;
 
 /**
  * Superclass of JUnit tests that process templates but aren't practical to implement via {@link TemplateTestSuite}. 

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/5be880de/src/test/java/freemarker/test/TestUtil.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/test/TestUtil.java b/src/test/java/freemarker/test/TestUtil.java
deleted file mode 100644
index 23669c0..0000000
--- a/src/test/java/freemarker/test/TestUtil.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package freemarker.test;
-
-import freemarker.template.Configuration;
-import freemarker.template.Version;
-
-public final class TestUtil {
-    
-    private TestUtil() {
-        // Not meant to be instantiated
-    }
-
-    public static String removeTxtCopyrightComment(String s) {
-        if (!s.startsWith("/*")) {
-            return s;
-        }
-        
-        int commentEnd = s.indexOf("*/");
-        if (commentEnd == -1) {
-            return s;
-        }
-        commentEnd += 2;
-        if (commentEnd < s.length()) {
-            char c = s.charAt(commentEnd);
-            if (c == '\n' || c == '\r') {
-                commentEnd++;
-                if (c == '\r' && commentEnd < s.length()) {
-                    if (s.charAt(commentEnd) == '\n') {
-                        commentEnd++;
-                    }
-                }
-            }
-        }
-        
-        String comment = s.substring(0, commentEnd);
-        int copyrightIdx = comment.indexOf("copyright");
-        if (copyrightIdx == -1) {
-            copyrightIdx = comment.indexOf("Copyright");
-        }
-        if (copyrightIdx == -1) {
-            return s;
-        }
-        
-        return s.substring(commentEnd);
-    }
-    
-    public static String removeFTLCopyrightComment(String ftl) {
-        if (ftl.contains("<#ftl ns_prefixes = {\"D\" : \"http://example.com/eBook\"}>")) {
-            System.out.println();
-        }
-        
-        int copyrightIdx = ftl.indexOf("copyright");
-        if (copyrightIdx == -1) {
-            copyrightIdx = ftl.indexOf("Copyright");
-        }
-        if (copyrightIdx == -1) {
-            return ftl;
-        }
-        
-        final int commentFirstIdx;
-        final boolean squareBracketTagSyntax;
-        {
-            String ftlBeforeCopyright = ftl.substring(0, copyrightIdx);
-            int abCommentStart = ftlBeforeCopyright.lastIndexOf("<#--");
-            int sbCommentStart = ftlBeforeCopyright.lastIndexOf("[#--");
-            squareBracketTagSyntax = sbCommentStart > abCommentStart;
-            commentFirstIdx = squareBracketTagSyntax ? sbCommentStart : abCommentStart;
-            if (commentFirstIdx == -1) {
-                throw new AssertionError("Can't find copyright comment start");
-            }
-        }
-        
-        final int commentLastIdx;
-        {
-            int commentEndStart = ftl.indexOf(squareBracketTagSyntax ? "--]" : "-->", copyrightIdx);
-            if (commentEndStart == -1) {
-                throw new AssertionError("Can't find copyright comment end");
-            }
-            commentLastIdx = commentEndStart + 2;
-        }
-        
-        final int afterCommentNLChars;
-        if (commentLastIdx + 1 < ftl.length()) {
-            char afterCommentChar = ftl.charAt(commentLastIdx + 1);
-            if (afterCommentChar == '\n' || afterCommentChar == '\r') {
-                if (afterCommentChar == '\r' && commentLastIdx + 2 < ftl.length() && ftl.charAt(commentLastIdx + 2) == '\n') {
-                    afterCommentNLChars = 2;
-                } else {
-                    afterCommentNLChars = 1;
-                }
-            } else {
-                afterCommentNLChars = 0;
-            }
-        } else {
-            afterCommentNLChars = 0;
-        }
-            
-        return ftl.substring(0, commentFirstIdx) + ftl.substring(commentLastIdx + afterCommentNLChars + 1);
-    }
-
-    /**
-     * Returns the closes FreeMarker version number that doesn't exit yet (so it's illegal).
-     */
-    public static Version getClosestFutureVersion() {
-        Version v = Configuration.getVersion();
-        return new Version(v.getMajor(), v.getMinor(), v.getMicro() + 1);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/5be880de/src/test/java/freemarker/test/servlet/WebAppTestCase.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/test/servlet/WebAppTestCase.java b/src/test/java/freemarker/test/servlet/WebAppTestCase.java
index 6bd7f44..0df5d54 100644
--- a/src/test/java/freemarker/test/servlet/WebAppTestCase.java
+++ b/src/test/java/freemarker/test/servlet/WebAppTestCase.java
@@ -44,7 +44,7 @@ import org.slf4j.LoggerFactory;
 
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import freemarker.test.ResourcesExtractor;
-import freemarker.test.TestUtil;
+import freemarker.test.utility.TestUtil;
 
 public class WebAppTestCase {
 

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/5be880de/src/test/java/freemarker/test/templatesuite/models/OverloadedMethods2.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/test/templatesuite/models/OverloadedMethods2.java b/src/test/java/freemarker/test/templatesuite/models/OverloadedMethods2.java
index 9f8e055..833e590 100644
--- a/src/test/java/freemarker/test/templatesuite/models/OverloadedMethods2.java
+++ b/src/test/java/freemarker/test/templatesuite/models/OverloadedMethods2.java
@@ -39,7 +39,7 @@ import freemarker.template.TemplateModel;
 import freemarker.template.TemplateModelException;
 import freemarker.template.TemplateNumberModel;
 import freemarker.template.utility.StringUtil;
-import freemarker.test.utility.Helpers;
+import freemarker.test.utility.TestUtil;
 
 public class OverloadedMethods2 {
 
@@ -321,80 +321,80 @@ public class OverloadedMethods2 {
     }
 
     public String varargs1(String s, int... xs) {
-        return "varargs1(String s = " + StringUtil.jQuote(s) + ", int... xs = " + Helpers.arrayToString(xs) + ")";
+        return "varargs1(String s = " + StringUtil.jQuote(s) + ", int... xs = " + TestUtil.arrayToString(xs) + ")";
     }
 
     public String varargs1(String s, double... xs) {
-        return "varargs1(String s = " + StringUtil.jQuote(s) + ", double... xs = " + Helpers.arrayToString(xs) + ")";
+        return "varargs1(String s = " + StringUtil.jQuote(s) + ", double... xs = " + TestUtil.arrayToString(xs) + ")";
     }
 
     public String varargs1(String s, Object... xs) {
-        return "varargs1(String s = " + StringUtil.jQuote(s) + ", Object... xs = " + Helpers.arrayToString(xs) + ")";
+        return "varargs1(String s = " + StringUtil.jQuote(s) + ", Object... xs = " + TestUtil.arrayToString(xs) + ")";
     }
 
     public String varargs1(Object s, Object... xs) {
-        return "varargs1(Object s = " + s + ", Object... xs = " + Helpers.arrayToString(xs) + ")";
+        return "varargs1(Object s = " + s + ", Object... xs = " + TestUtil.arrayToString(xs) + ")";
     }
 
     public String varargs2(int... xs) {
-        return "varargs2(int... xs = " + Helpers.arrayToString(xs) + ")";
+        return "varargs2(int... xs = " + TestUtil.arrayToString(xs) + ")";
     }
 
     public String varargs2(double... xs) {
-        return "varargs2(double... xs = " + Helpers.arrayToString(xs) + ")";
+        return "varargs2(double... xs = " + TestUtil.arrayToString(xs) + ")";
     }
 
     public String varargs3(String... xs) {
-        return "varargs3(String... xs = " + Helpers.arrayToString(xs) + ")";
+        return "varargs3(String... xs = " + TestUtil.arrayToString(xs) + ")";
     }
 
     public String varargs3(Comparable... xs) {
-        return "varargs3(Comparable... xs = " + Helpers.arrayToString(xs) + ")";
+        return "varargs3(Comparable... xs = " + TestUtil.arrayToString(xs) + ")";
     }
     
     public String varargs3(Object... xs) {
-        return "varargs3(Object... xs = " + Helpers.arrayToString(xs) + ")";
+        return "varargs3(Object... xs = " + TestUtil.arrayToString(xs) + ")";
     }
     
     public String varargs4(Integer... xs) {
-        return "varargs4(Integer... xs = " + Helpers.arrayToString(xs) + ")";
+        return "varargs4(Integer... xs = " + TestUtil.arrayToString(xs) + ")";
     }
 
     public String varargs4(int... xs) {
-        return "varargs4(int... xs = " + Helpers.arrayToString(xs) + ")";
+        return "varargs4(int... xs = " + TestUtil.arrayToString(xs) + ")";
     }
 
     public String varargs5(int... xs) {
-        return "varargs5(int... xs = " + Helpers.arrayToString(xs) + ")";
+        return "varargs5(int... xs = " + TestUtil.arrayToString(xs) + ")";
     }
     
     public String varargs5(int a1, int... xs) {
-        return "varargs5(int a1 = " + a1 + ", int... xs = " + Helpers.arrayToString(xs) + ")";
+        return "varargs5(int a1 = " + a1 + ", int... xs = " + TestUtil.arrayToString(xs) + ")";
     }
     
     public String varargs5(int a1, int a2, int... xs) {
-        return "varargs5(int a1 = " + a1 + ", int a2 = " + a2 + ", int... xs = " + Helpers.arrayToString(xs) + ")";
+        return "varargs5(int a1 = " + a1 + ", int a2 = " + a2 + ", int... xs = " + TestUtil.arrayToString(xs) + ")";
     }
 
     public String varargs5(int a1, int a2, int a3, int... xs) {
         return "varargs5(int a1 = " + a1 + ", int a2 = " + a2 + ", int a3 = " + a3
-                + ", int... xs = " + Helpers.arrayToString(xs) + ")";
+                + ", int... xs = " + TestUtil.arrayToString(xs) + ")";
     }
 
     public String varargs6(String a1, int... xs) {
-        return "varargs6(String a1 = " + a1 + ", int... xs = " + Helpers.arrayToString(xs) + ")";
+        return "varargs6(String a1 = " + a1 + ", int... xs = " + TestUtil.arrayToString(xs) + ")";
     }
     
     public String varargs6(Object a1, int a2, int... xs) {
-        return "varargs6(Object a1 = " + a1 + ", int a2 = " + a2 + ", int... xs = " + Helpers.arrayToString(xs) + ")";
+        return "varargs6(Object a1 = " + a1 + ", int a2 = " + a2 + ", int... xs = " + TestUtil.arrayToString(xs) + ")";
     }
     
     public String varargs7(int... xs) {
-        return "varargs7(int... xs = " + Helpers.arrayToString(xs) + ")";
+        return "varargs7(int... xs = " + TestUtil.arrayToString(xs) + ")";
     }
     
     public String varargs7(short a1, int... xs) {
-        return "varargs7(short a1 = " + a1 + ", int... xs = " + Helpers.arrayToString(xs) + ")";
+        return "varargs7(short a1 = " + a1 + ", int... xs = " + TestUtil.arrayToString(xs) + ")";
     }
     
     public String mNullAmbiguous(String s) {
@@ -430,11 +430,11 @@ public class OverloadedMethods2 {
     }
     
     public String mVarargsIgnoredTail(int i, double... ds) {
-        return "mVarargsIgnoredTail(int i = " + i + ", double... ds = " + Helpers.arrayToString(ds) + ")"; 
+        return "mVarargsIgnoredTail(int i = " + i + ", double... ds = " + TestUtil.arrayToString(ds) + ")"; 
     }
     
     public String mVarargsIgnoredTail(int... is) {
-        return "mVarargsIgnoredTail(int... is = " + Helpers.arrayToString(is) + ")"; 
+        return "mVarargsIgnoredTail(int... is = " + TestUtil.arrayToString(is) + ")"; 
     }
     
     public String mLowRankWins(int x, int y, Object o) {
@@ -473,19 +473,19 @@ public class OverloadedMethods2 {
     }
 
     public String mSeqToArrayNonOverloaded(String[] items, String s) {
-        return "mSeqToArrayNonOverloaded(String[] " + Helpers.arrayToString(items) + ", String " + s + ")";
+        return "mSeqToArrayNonOverloaded(String[] " + TestUtil.arrayToString(items) + ", String " + s + ")";
     }
     
     public String mSeqToArrayGoodHint(String[] items, String s) {
-        return "mSeqToArrayGoodHint(String[] " + Helpers.arrayToString(items) + ", String " + s + ")";
+        return "mSeqToArrayGoodHint(String[] " + TestUtil.arrayToString(items) + ", String " + s + ")";
     }
 
     public String mSeqToArrayGoodHint(String[] items, int i) {
-        return "mSeqToArrayGoodHint(String[] " + Helpers.arrayToString(items) + ", int " + i + ")";
+        return "mSeqToArrayGoodHint(String[] " + TestUtil.arrayToString(items) + ", int " + i + ")";
     }
 
     public String mSeqToArrayGoodHint2(String[] items, String s) {
-        return "mSeqToArrayGoodHint2(String[] " + Helpers.arrayToString(items) + ", String " + s + ")";
+        return "mSeqToArrayGoodHint2(String[] " + TestUtil.arrayToString(items) + ", String " + s + ")";
     }
 
     public String mSeqToArrayGoodHint2(String item) {
@@ -493,7 +493,7 @@ public class OverloadedMethods2 {
     }
     
     public String mSeqToArrayPoorHint(String[] items, String s) {
-        return "mSeqToArrayPoorHint(String[] " + Helpers.arrayToString(items) + ", String " + s + ")";
+        return "mSeqToArrayPoorHint(String[] " + TestUtil.arrayToString(items) + ", String " + s + ")";
     }
 
     public String mSeqToArrayPoorHint(String item, int i) {
@@ -501,7 +501,7 @@ public class OverloadedMethods2 {
     }
 
     public String mSeqToArrayPoorHint2(String[] items) {
-        return "mSeqToArrayPoorHint2(String[] " + Helpers.arrayToString(items) + ")";
+        return "mSeqToArrayPoorHint2(String[] " + TestUtil.arrayToString(items) + ")";
     }
 
     public String mSeqToArrayPoorHint2(String item) {
@@ -509,43 +509,43 @@ public class OverloadedMethods2 {
     }
     
     public String mSeqToArrayPoorHint3(String[] items) {
-        return "mSeqToArrayPoorHint3(String[] " + Helpers.arrayToString(items) + ")";
+        return "mSeqToArrayPoorHint3(String[] " + TestUtil.arrayToString(items) + ")";
     }
 
     public String mSeqToArrayPoorHint3(int[] items) {
-        return "mSeqToArrayPoorHint3(int[] " + Helpers.arrayToString(items) + ")";
+        return "mSeqToArrayPoorHint3(int[] " + TestUtil.arrayToString(items) + ")";
     }
 
     public String mStringArrayVsListPreference(String[] items) {
-        return "mStringArrayVsListPreference(String[] " + Helpers.arrayToString(items) + ")";
+        return "mStringArrayVsListPreference(String[] " + TestUtil.arrayToString(items) + ")";
     }
 
     public String mStringArrayVsListPreference(List items) {
-        return "mStringArrayVsListPreference(List " + Helpers.listToString(items) + ")";
+        return "mStringArrayVsListPreference(List " + TestUtil.listToString(items) + ")";
     }
 
     public String mStringArrayVsObjectArrayPreference(String[] items) {
-        return "mStringArrayVsObjectArrayPreference(String[] " + Helpers.arrayToString(items) + ")";
+        return "mStringArrayVsObjectArrayPreference(String[] " + TestUtil.arrayToString(items) + ")";
     }
 
     public String mStringArrayVsObjectArrayPreference(Object[] items) {
-        return "mStringArrayVsObjectArrayPreference(Object[] " + Helpers.arrayToString(items) + ")";
+        return "mStringArrayVsObjectArrayPreference(Object[] " + TestUtil.arrayToString(items) + ")";
     }
 
     public String mIntArrayVsIntegerArrayPreference(int[] items) {
-        return "mIntArrayVsIntegerArrayPreference(int[] " + Helpers.arrayToString(items) + ")";
+        return "mIntArrayVsIntegerArrayPreference(int[] " + TestUtil.arrayToString(items) + ")";
     }
 
     public String mIntArrayVsIntegerArrayPreference(Integer[] items) {
-        return "mIntArrayVsIntegerArrayPreference(Integer[] " + Helpers.arrayToString(items) + ")";
+        return "mIntArrayVsIntegerArrayPreference(Integer[] " + TestUtil.arrayToString(items) + ")";
     }
     
     public String mIntArrayNonOverloaded(int[] items) {
-        return "mIntArrayNonOverloaded(int[] " + Helpers.arrayToString(items) + ")";
+        return "mIntArrayNonOverloaded(int[] " + TestUtil.arrayToString(items) + ")";
     }
 
     public String mIntegerArrayNonOverloaded(Integer[] items) {
-        return "mIntegerArrayNonOverloaded(Integer[] " + Helpers.arrayToString(items) + ")";
+        return "mIntegerArrayNonOverloaded(Integer[] " + TestUtil.arrayToString(items) + ")";
     }
 
     public String mIntegerListNonOverloaded(List<Integer> items) {
@@ -557,7 +557,7 @@ public class OverloadedMethods2 {
     }
 
     public String mStringArrayNonOverloaded(String[] items) {
-        return "mStringArrayNonOverloaded(String[] " + Helpers.arrayToString(items) + ")";
+        return "mStringArrayNonOverloaded(String[] " + TestUtil.arrayToString(items) + ")";
     }
 
     public String mObjectListNonOverloaded(List<Object> items) {
@@ -565,11 +565,11 @@ public class OverloadedMethods2 {
     }
 
     public String mObjectArrayNonOverloaded(Object[] items) {
-        return "mObjectArrayNonOverloaded(Object[] " + Helpers.arrayToString(items) + ")";
+        return "mObjectArrayNonOverloaded(Object[] " + TestUtil.arrayToString(items) + ")";
     }
 
     public String mIntegerArrayOverloaded(Integer[] items, int i) {
-        return "mIntegerArrayOverloaded(Integer[] " + Helpers.arrayToString(items) + ", int " + i + ")";
+        return "mIntegerArrayOverloaded(Integer[] " + TestUtil.arrayToString(items) + ", int " + i + ")";
     }
 
     public String mIntegerArrayOverloaded(Object obj, boolean b) {
@@ -577,7 +577,7 @@ public class OverloadedMethods2 {
     }
 
     public String mStringArrayOverloaded(String[] items, int i) {
-        return "mStringArrayOverloaded(String[] " + Helpers.arrayToString(items) + ", int " + i + ")";
+        return "mStringArrayOverloaded(String[] " + TestUtil.arrayToString(items) + ", int " + i + ")";
     }
 
     public String mStringArrayOverloaded(Object obj, boolean b) {
@@ -585,11 +585,11 @@ public class OverloadedMethods2 {
     }
 
     public String mCharArrayOverloaded(char[] items, int i) {
-        return "mCharArrayOverloaded(char[] " + Helpers.arrayToString(items) + ", int " + i + ")";
+        return "mCharArrayOverloaded(char[] " + TestUtil.arrayToString(items) + ", int " + i + ")";
     }
 
     public String mCharArrayOverloaded(Character[] items, String s) {
-        return "mCharArrayOverloaded(Character[] " + Helpers.arrayToString(items) + ", String " + s + ")";
+        return "mCharArrayOverloaded(Character[] " + TestUtil.arrayToString(items) + ", String " + s + ")";
     }
     
     public String mCharArrayOverloaded(Object obj, boolean b) {
@@ -597,7 +597,7 @@ public class OverloadedMethods2 {
     }
 
     public String mStringArrayArrayOverloaded(String[][] arrayArray, int i) {
-        return "mStringArrayArrayOverloaded(String[][] " + Helpers.arrayToString(arrayArray) + ", int " + i + ")";
+        return "mStringArrayArrayOverloaded(String[][] " + TestUtil.arrayToString(arrayArray) + ", int " + i + ")";
     }
     
     public String mStringArrayArrayOverloaded(Object obj, boolean b) {
@@ -605,7 +605,7 @@ public class OverloadedMethods2 {
     }
     
     public String mIntArrayArrayOverloaded(int[][] xss) {
-        return "mIntArrayArrayOverloaded(" + Helpers.arrayToString(xss) + ")";
+        return "mIntArrayArrayOverloaded(" + TestUtil.arrayToString(xss) + ")";
     }
 
     public String mIntArrayArrayOverloaded(String s) {
@@ -613,7 +613,7 @@ public class OverloadedMethods2 {
     }
     
     public String mArrayOfListsOverloaded(List[] xss) {
-        return "mArrayOfListsOverloaded(" + Helpers.arrayToString(xss) + ")";
+        return "mArrayOfListsOverloaded(" + TestUtil.arrayToString(xss) + ")";
     }
 
     public String mArrayOfListsOverloaded(String x) {
@@ -621,31 +621,31 @@ public class OverloadedMethods2 {
     }
     
     public String mIntArrayArrayNonOverloaded(int[][] xss) {
-        return "mIntArrayArrayNonOverloaded(" + Helpers.arrayToString(xss) + ")";
+        return "mIntArrayArrayNonOverloaded(" + TestUtil.arrayToString(xss) + ")";
     }
 
     public String mArrayOfListsNonOverloaded(List[] xss) {
-        return "mArrayOfListsNonOverloaded(" + Helpers.arrayToString(xss) + ")";
+        return "mArrayOfListsNonOverloaded(" + TestUtil.arrayToString(xss) + ")";
     }
     
     public String mStringArrayVarargsNonOverloaded(String... items) {
-        return "mStringArrayVarargsNonOverloaded(String[] " + Helpers.arrayToString(items) + ")";
+        return "mStringArrayVarargsNonOverloaded(String[] " + TestUtil.arrayToString(items) + ")";
     }
 
     public String mStringArrayVarargsOverloaded(String... items) {
-        return "mStringArrayVarargsNonOverloaded(String[] " + Helpers.arrayToString(items) + ")";
+        return "mStringArrayVarargsNonOverloaded(String[] " + TestUtil.arrayToString(items) + ")";
     }
 
     public String mStringArrayVarargsOverloaded1(String... items) {
-        return "mStringArrayVarargsOverloaded1(String[] " + Helpers.arrayToString(items) + ")";
+        return "mStringArrayVarargsOverloaded1(String[] " + TestUtil.arrayToString(items) + ")";
     }
 
     public String mStringArrayVarargsOverloaded1(List<String> items) {
-        return "mStringArrayVarargsOverloaded1(List " + Helpers.listToString(items) + ")";
+        return "mStringArrayVarargsOverloaded1(List " + TestUtil.listToString(items) + ")";
     }
 
     public String mStringArrayVarargsOverloaded2(String... items) {
-        return "mStringArrayVarargsOverloaded2(String[] " + Helpers.arrayToString(items) + ")";
+        return "mStringArrayVarargsOverloaded2(String[] " + TestUtil.arrayToString(items) + ")";
     }
 
     public String mStringArrayVarargsOverloaded2(String item) {
@@ -653,7 +653,7 @@ public class OverloadedMethods2 {
     }
     
     public String mStringArrayVarargsOverloaded3(String... items) {
-        return "mStringArrayVarargsOverloaded3(String[] " + Helpers.arrayToString(items) + ")";
+        return "mStringArrayVarargsOverloaded3(String[] " + TestUtil.arrayToString(items) + ")";
     }
 
     public String mStringArrayVarargsOverloaded3(String item1, String item2) {
@@ -661,15 +661,15 @@ public class OverloadedMethods2 {
     }
     
     public String mStringArrayVarargsOverloaded4(String... items) {
-        return "mStringArrayVarargsOverloaded4(String[] " + Helpers.arrayToString(items) + ")";
+        return "mStringArrayVarargsOverloaded4(String[] " + TestUtil.arrayToString(items) + ")";
     }
 
     public String mStringArrayVarargsOverloaded4(List... items) {
-        return "mStringArrayVarargsOverloaded4(List[] " + Helpers.arrayToString(items) + ")";
+        return "mStringArrayVarargsOverloaded4(List[] " + TestUtil.arrayToString(items) + ")";
     }
     
     public String mListOrString(List<String> items) {
-        return "mListOrString(List " + Helpers.listToString(items) + ")";
+        return "mListOrString(List " + TestUtil.listToString(items) + ")";
     }
 
     public String mListOrString(String item) {
@@ -677,7 +677,7 @@ public class OverloadedMethods2 {
     }
 
     public String mListListOrString(List<List<Object>> items) {
-        return "mListListOrString(List " + Helpers.listToString(items) + ")";
+        return "mListListOrString(List " + TestUtil.listToString(items) + ")";
     }
 
     public String mListListOrString(String item) {
@@ -693,11 +693,11 @@ public class OverloadedMethods2 {
     }
 
     public String mMapOrBooleanVarargs(Map... v) {
-        return "mMapOrBooleanVarargs(Map... " + Helpers.arrayToString(v) + ")";
+        return "mMapOrBooleanVarargs(Map... " + TestUtil.arrayToString(v) + ")";
     }
 
     public String mMapOrBooleanVarargs(boolean... v) {
-        return "mMapOrBooleanVarargs(boolean... " + Helpers.arrayToString(v) + ")";
+        return "mMapOrBooleanVarargs(boolean... " + TestUtil.arrayToString(v) + ")";
     }
 
     public String mMapOrBooleanFixedAndVarargs(Map v) {
@@ -709,11 +709,11 @@ public class OverloadedMethods2 {
     }
 
     public String mMapOrBooleanFixedAndVarargs(Map... v) {
-        return "mMapOrBooleanFixedAndVarargs(Map... " + Helpers.arrayToString(v) + ")";
+        return "mMapOrBooleanFixedAndVarargs(Map... " + TestUtil.arrayToString(v) + ")";
     }
 
     public String mMapOrBooleanFixedAndVarargs(boolean... v) {
-        return "mMapOrBooleanFixedAndVarargs(boolean... " + Helpers.arrayToString(v) + ")";
+        return "mMapOrBooleanFixedAndVarargs(boolean... " + TestUtil.arrayToString(v) + ")";
     }
     
     public String mNumberOrArray(Number v) {
@@ -721,7 +721,7 @@ public class OverloadedMethods2 {
     }
 
     public String mNumberOrArray(Object[] v) {
-        return "mNumberOrArray(Object[] " + Helpers.arrayToString(v) + ")";
+        return "mNumberOrArray(Object[] " + TestUtil.arrayToString(v) + ")";
     }
     
     public String mIntOrArray(int v) {
@@ -729,7 +729,7 @@ public class OverloadedMethods2 {
     }
 
     public String mIntOrArray(Object[] v) {
-        return "mIntOrArray(Object[] " + Helpers.arrayToString(v) + ")";
+        return "mIntOrArray(Object[] " + TestUtil.arrayToString(v) + ")";
     }
 
     public String mDateOrArray(Date v) {
@@ -737,7 +737,7 @@ public class OverloadedMethods2 {
     }
 
     public String mDateOrArray(Object[] v) {
-        return "mDateOrArray(Object[] " + Helpers.arrayToString(v) + ")";
+        return "mDateOrArray(Object[] " + TestUtil.arrayToString(v) + ")";
     }
     
     public String mStringOrArray(String v) {
@@ -745,7 +745,7 @@ public class OverloadedMethods2 {
     }
 
     public String mStringOrArray(Object[] v) {
-        return "mStringOrArray(Object[] " + Helpers.arrayToString(v) + ")";
+        return "mStringOrArray(Object[] " + TestUtil.arrayToString(v) + ")";
     }
     
     public String mBooleanOrArray(boolean v) {
@@ -753,7 +753,7 @@ public class OverloadedMethods2 {
     }
 
     public String mBooleanOrArray(Object[] v) {
-        return "mBooleanOrArray(Object[] " + Helpers.arrayToString(v) + ")";
+        return "mBooleanOrArray(Object[] " + TestUtil.arrayToString(v) + ")";
     }
     
     public String mMapOrArray(Map v) {
@@ -761,7 +761,7 @@ public class OverloadedMethods2 {
     }
 
     public String mMapOrArray(Object[] v) {
-        return "mMapOrArray(Object[] " + Helpers.arrayToString(v) + ")";
+        return "mMapOrArray(Object[] " + TestUtil.arrayToString(v) + ")";
     }
     
     public String mListOrArray(List v) {
@@ -769,7 +769,7 @@ public class OverloadedMethods2 {
     }
 
     public String mListOrArray(Object[] v) {
-        return "mListOrArray(Object[] " + Helpers.arrayToString(v) + ")";
+        return "mListOrArray(Object[] " + TestUtil.arrayToString(v) + ")";
     }
     
     public String mSetOrArray(Set v) {
@@ -777,7 +777,7 @@ public class OverloadedMethods2 {
     }
 
     public String mSetOrArray(Object[] v) {
-        return "mSetOrArray(Object[] " + Helpers.arrayToString(v) + ")";
+        return "mSetOrArray(Object[] " + TestUtil.arrayToString(v) + ")";
     }
     
     public String mCharNonOverloaded(char c) {
@@ -1010,7 +1010,7 @@ public class OverloadedMethods2 {
     }
 
     public String bugReport363(Object... fields) {
-        return "Executed: testMethod(Object... fields) on input: fields=" + Helpers.arrayToString(fields);
+        return "Executed: testMethod(Object... fields) on input: fields=" + TestUtil.arrayToString(fields);
     }
     
     private static class MyAdapterNumberModel implements TemplateNumberModel, AdapterTemplateModel {

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/5be880de/src/test/java/freemarker/test/utility/FileTestCase.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/test/utility/FileTestCase.java b/src/test/java/freemarker/test/utility/FileTestCase.java
index 4989fb7..c85496c 100644
--- a/src/test/java/freemarker/test/utility/FileTestCase.java
+++ b/src/test/java/freemarker/test/utility/FileTestCase.java
@@ -33,7 +33,6 @@ import java.net.URL;
 
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import freemarker.template.utility.StringUtil;
-import freemarker.test.TestUtil;
 import junit.framework.AssertionFailedError;
 import junit.framework.TestCase;
 

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/5be880de/src/test/java/freemarker/test/utility/Helpers.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/test/utility/Helpers.java b/src/test/java/freemarker/test/utility/Helpers.java
deleted file mode 100644
index 7f06f7d..0000000
--- a/src/test/java/freemarker/test/utility/Helpers.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package freemarker.test.utility;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Set;
-
-public class Helpers {
-
-    private Helpers() { }
-
-    public static String arrayToString(double[] xs) {
-        StringBuilder sb = new StringBuilder();
-        
-        sb.append('[');
-        for (double x : xs) {
-            if (sb.length() != 1) sb.append(", ");
-            sb.append(x);
-        }
-        sb.append(']');
-        
-        return sb.toString();
-    }
-
-    public static String arrayToString(Object[] array) {
-        if (array == null) return "null";
-        
-        StringBuilder sb = new StringBuilder();
-        sb.append('[');
-        for (int i = 0; i < array.length; i++) {
-            if (i != 0) {
-                sb.append(", ");
-            }
-            sb.append(array[i]);
-        }
-        sb.append(']');
-        return sb.toString();
-    }
-
-    public static String arrayToString(Object[][] arrayArray) {
-        if (arrayArray == null) return "null";
-        
-        StringBuilder sb = new StringBuilder();
-        sb.append('[');
-        boolean first = true;
-        for (Object[] array : arrayArray) {
-            if (!first) {
-                sb.append(", ");
-            } else {
-                first = false;
-            }
-            sb.append(arrayToString(array));
-        }
-        sb.append(']');
-        return sb.toString();
-    }
-    
-    public static String arrayToString(int[] array) {
-        if (array == null) return "null";
-        
-        StringBuilder sb = new StringBuilder();
-        sb.append('[');
-        for (int i = 0; i < array.length; i++) {
-            if (i != 0) {
-                sb.append(", ");
-            }
-            sb.append(array[i]);
-        }
-        sb.append(']');
-        return sb.toString();
-    }
-    
-    public static String arrayToString(int[][] xss) {
-        if (xss == null) return "null";
-        
-        StringBuilder sb = new StringBuilder();
-        sb.append('[');
-        for (int i = 0; i < xss.length; i++) {
-            if (i != 0) {
-                sb.append(", ");
-            }
-            sb.append(arrayToString(xss[i]));
-        }
-        sb.append(']');
-        return sb.toString();
-    }
-
-    public static String arrayToString(char[] array) {
-        if (array == null) return "null";
-        
-        StringBuilder sb = new StringBuilder();
-        sb.append('[');
-        for (int i = 0; i < array.length; i++) {
-            if (i != 0) {
-                sb.append(", ");
-            }
-            sb.append(array[i]);
-        }
-        sb.append(']');
-        return sb.toString();
-    }
-    
-    public static String arrayToString(boolean[] array) {
-        if (array == null) return "null";
-        
-        StringBuilder sb = new StringBuilder();
-        sb.append('[');
-        for (int i = 0; i < array.length; i++) {
-            if (i != 0) {
-                sb.append(", ");
-            }
-            sb.append(array[i]);
-        }
-        sb.append(']');
-        return sb.toString();
-    }
-
-    public static String listToString(List<?> list) {
-        return collectionToString("", list);
-    }
-    
-    
-    public static String setToString(Set<?> list) {
-        return collectionToString("Set", list);
-    }
-    
-    private static String collectionToString(String prefix, Collection<?> list) {
-        if (list == null) return "null";
-        
-        StringBuilder sb = new StringBuilder();
-        sb.append(prefix);
-        sb.append('[');
-        boolean first = true;
-        for (Object item : list) {
-            if (!first) {
-                sb.append(", ");
-            } else {
-                first = false;
-            }
-            sb.append(item instanceof Object[] ? arrayToString((Object[]) item) : item);
-        }
-        sb.append(']');
-        return sb.toString();
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/5be880de/src/test/java/freemarker/test/utility/TestUtil.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/test/utility/TestUtil.java b/src/test/java/freemarker/test/utility/TestUtil.java
new file mode 100644
index 0000000..e12a9fa
--- /dev/null
+++ b/src/test/java/freemarker/test/utility/TestUtil.java
@@ -0,0 +1,266 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package freemarker.test.utility;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
+import freemarker.template.Configuration;
+import freemarker.template.Version;
+
+/**
+ * Testing related helper methods that didn't fit esewhere.
+ */
+public class TestUtil {
+
+    private TestUtil() { }
+
+    public static String arrayToString(double[] xs) {
+        StringBuilder sb = new StringBuilder();
+        
+        sb.append('[');
+        for (double x : xs) {
+            if (sb.length() != 1) sb.append(", ");
+            sb.append(x);
+        }
+        sb.append(']');
+        
+        return sb.toString();
+    }
+
+    public static String arrayToString(Object[] array) {
+        if (array == null) return "null";
+        
+        StringBuilder sb = new StringBuilder();
+        sb.append('[');
+        for (int i = 0; i < array.length; i++) {
+            if (i != 0) {
+                sb.append(", ");
+            }
+            sb.append(array[i]);
+        }
+        sb.append(']');
+        return sb.toString();
+    }
+
+    public static String arrayToString(Object[][] arrayArray) {
+        if (arrayArray == null) return "null";
+        
+        StringBuilder sb = new StringBuilder();
+        sb.append('[');
+        boolean first = true;
+        for (Object[] array : arrayArray) {
+            if (!first) {
+                sb.append(", ");
+            } else {
+                first = false;
+            }
+            sb.append(arrayToString(array));
+        }
+        sb.append(']');
+        return sb.toString();
+    }
+    
+    public static String arrayToString(int[] array) {
+        if (array == null) return "null";
+        
+        StringBuilder sb = new StringBuilder();
+        sb.append('[');
+        for (int i = 0; i < array.length; i++) {
+            if (i != 0) {
+                sb.append(", ");
+            }
+            sb.append(array[i]);
+        }
+        sb.append(']');
+        return sb.toString();
+    }
+    
+    public static String arrayToString(int[][] xss) {
+        if (xss == null) return "null";
+        
+        StringBuilder sb = new StringBuilder();
+        sb.append('[');
+        for (int i = 0; i < xss.length; i++) {
+            if (i != 0) {
+                sb.append(", ");
+            }
+            sb.append(arrayToString(xss[i]));
+        }
+        sb.append(']');
+        return sb.toString();
+    }
+
+    public static String arrayToString(char[] array) {
+        if (array == null) return "null";
+        
+        StringBuilder sb = new StringBuilder();
+        sb.append('[');
+        for (int i = 0; i < array.length; i++) {
+            if (i != 0) {
+                sb.append(", ");
+            }
+            sb.append(array[i]);
+        }
+        sb.append(']');
+        return sb.toString();
+    }
+    
+    public static String arrayToString(boolean[] array) {
+        if (array == null) return "null";
+        
+        StringBuilder sb = new StringBuilder();
+        sb.append('[');
+        for (int i = 0; i < array.length; i++) {
+            if (i != 0) {
+                sb.append(", ");
+            }
+            sb.append(array[i]);
+        }
+        sb.append(']');
+        return sb.toString();
+    }
+
+    public static String listToString(List<?> list) {
+        return collectionToString("", list);
+    }
+    
+    
+    public static String setToString(Set<?> list) {
+        return collectionToString("Set", list);
+    }
+    
+    private static String collectionToString(String prefix, Collection<?> list) {
+        if (list == null) return "null";
+        
+        StringBuilder sb = new StringBuilder();
+        sb.append(prefix);
+        sb.append('[');
+        boolean first = true;
+        for (Object item : list) {
+            if (!first) {
+                sb.append(", ");
+            } else {
+                first = false;
+            }
+            sb.append(item instanceof Object[] ? arrayToString((Object[]) item) : item);
+        }
+        sb.append(']');
+        return sb.toString();
+    }
+
+    public static String removeTxtCopyrightComment(String s) {
+        if (!s.startsWith("/*")) {
+            return s;
+        }
+        
+        int commentEnd = s.indexOf("*/");
+        if (commentEnd == -1) {
+            return s;
+        }
+        commentEnd += 2;
+        if (commentEnd < s.length()) {
+            char c = s.charAt(commentEnd);
+            if (c == '\n' || c == '\r') {
+                commentEnd++;
+                if (c == '\r' && commentEnd < s.length()) {
+                    if (s.charAt(commentEnd) == '\n') {
+                        commentEnd++;
+                    }
+                }
+            }
+        }
+        
+        String comment = s.substring(0, commentEnd);
+        int copyrightIdx = comment.indexOf("copyright");
+        if (copyrightIdx == -1) {
+            copyrightIdx = comment.indexOf("Copyright");
+        }
+        if (copyrightIdx == -1) {
+            return s;
+        }
+        
+        return s.substring(commentEnd);
+    }
+
+    public static String removeFTLCopyrightComment(String ftl) {
+        if (ftl.contains("<#ftl ns_prefixes = {\"D\" : \"http://example.com/eBook\"}>")) {
+            System.out.println();
+        }
+        
+        int copyrightIdx = ftl.indexOf("copyright");
+        if (copyrightIdx == -1) {
+            copyrightIdx = ftl.indexOf("Copyright");
+        }
+        if (copyrightIdx == -1) {
+            return ftl;
+        }
+        
+        final int commentFirstIdx;
+        final boolean squareBracketTagSyntax;
+        {
+            String ftlBeforeCopyright = ftl.substring(0, copyrightIdx);
+            int abCommentStart = ftlBeforeCopyright.lastIndexOf("<#--");
+            int sbCommentStart = ftlBeforeCopyright.lastIndexOf("[#--");
+            squareBracketTagSyntax = sbCommentStart > abCommentStart;
+            commentFirstIdx = squareBracketTagSyntax ? sbCommentStart : abCommentStart;
+            if (commentFirstIdx == -1) {
+                throw new AssertionError("Can't find copyright comment start");
+            }
+        }
+        
+        final int commentLastIdx;
+        {
+            int commentEndStart = ftl.indexOf(squareBracketTagSyntax ? "--]" : "-->", copyrightIdx);
+            if (commentEndStart == -1) {
+                throw new AssertionError("Can't find copyright comment end");
+            }
+            commentLastIdx = commentEndStart + 2;
+        }
+        
+        final int afterCommentNLChars;
+        if (commentLastIdx + 1 < ftl.length()) {
+            char afterCommentChar = ftl.charAt(commentLastIdx + 1);
+            if (afterCommentChar == '\n' || afterCommentChar == '\r') {
+                if (afterCommentChar == '\r' && commentLastIdx + 2 < ftl.length() && ftl.charAt(commentLastIdx + 2) == '\n') {
+                    afterCommentNLChars = 2;
+                } else {
+                    afterCommentNLChars = 1;
+                }
+            } else {
+                afterCommentNLChars = 0;
+            }
+        } else {
+            afterCommentNLChars = 0;
+        }
+            
+        return ftl.substring(0, commentFirstIdx) + ftl.substring(commentLastIdx + afterCommentNLChars + 1);
+    }
+
+    /**
+     * Returns the closes FreeMarker version number that doesn't exit yet (so it's illegal).
+     */
+    public static Version getClosestFutureVersion() {
+        Version v = Configuration.getVersion();
+        return new Version(v.getMajor(), v.getMinor(), v.getMicro() + 1);
+    }
+    
+}