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 2018/02/28 08:54:48 UTC

[1/2] incubator-freemarker git commit: (JavaDoc improvement)

Repository: incubator-freemarker
Updated Branches:
  refs/heads/2.3-gae 5065cfe86 -> d7c654db6


(JavaDoc improvement)


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

Branch: refs/heads/2.3-gae
Commit: 16ad98c1ed7db20f55582afe9f800104e6fdbb79
Parents: 5065cfe
Author: ddekany <dd...@apache.org>
Authored: Wed Feb 28 09:49:00 2018 +0100
Committer: ddekany <dd...@apache.org>
Committed: Wed Feb 28 09:49:00 2018 +0100

----------------------------------------------------------------------
 src/main/java/freemarker/core/Environment.java | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/16ad98c1/src/main/java/freemarker/core/Environment.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/Environment.java b/src/main/java/freemarker/core/Environment.java
index 310ae9d..47b390a 100644
--- a/src/main/java/freemarker/core/Environment.java
+++ b/src/main/java/freemarker/core/Environment.java
@@ -2595,9 +2595,12 @@ public final class Environment extends Configurable {
      *
      * @param loadedTemplate
      *            The template to import. Note that it does <em>not</em> need to be a template returned by
-     *            {@link #getTemplateForImporting(String name)}.
+     *            {@link #getTemplateForImporting(String name)}. Not {@code null}.
      * @param targetNsVarName
-     *            The name of the FTL variable that will store the namespace.
+     *            The name of the FTL variable that will store the namespace. If {@code null}, the namespace
+     *            won't be stored in a variable (but it's still returned).
+     *            
+     * @return The namespace of the imported template, already initialized. 
      *            
      * @see #getTemplateForImporting(String name)
      * @see #importLib(Template includedTemplate, String namespaceVarName)


[2/2] incubator-freemarker git commit: Made freemarker.core.MessageUtil public but unpublished (so now other freemarker packages can use it)

Posted by dd...@apache.org.
Made freemarker.core.MessageUtil public but unpublished (so now other freemarker packages can use it)


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

Branch: refs/heads/2.3-gae
Commit: d7c654db6cb4c535f51eb22d63200e376f0b4bca
Parents: 16ad98c
Author: ddekany <dd...@apache.org>
Authored: Wed Feb 28 09:54:05 2018 +0100
Committer: ddekany <dd...@apache.org>
Committed: Wed Feb 28 09:54:05 2018 +0100

----------------------------------------------------------------------
 src/main/java/freemarker/core/BuiltIn.java      |  12 +-
 .../java/freemarker/core/BuiltInsForDates.java  |   4 +-
 .../core/BuiltInsForExistenceHandling.java      |   2 +-
 .../core/BuiltInsForMultipleTypes.java          |   4 +-
 .../freemarker/core/BuiltInsForSequences.java   |   6 +-
 .../core/BuiltInsForStringsBasic.java           |   6 +-
 .../freemarker/core/BuiltInsForStringsMisc.java |   8 +-
 src/main/java/freemarker/core/Environment.java  |  16 +-
 src/main/java/freemarker/core/EvalUtil.java     |   8 +-
 src/main/java/freemarker/core/Interpret.java    |   8 +-
 src/main/java/freemarker/core/Macro.java        |   2 +-
 src/main/java/freemarker/core/MessageUtil.java  | 354 ------------------
 .../java/freemarker/core/ParseException.java    |   2 +-
 .../freemarker/core/TemplateClassResolver.java  |   4 +-
 .../java/freemarker/core/TemplateObject.java    |   4 +-
 .../java/freemarker/core/TransformBlock.java    |   2 +-
 src/main/java/freemarker/core/UnifiedCall.java  |   4 +-
 ...nDateTypeFormattingUnsupportedException.java |   2 +-
 ...nownDateTypeParsingUnsupportedException.java |   2 +-
 .../java/freemarker/core/_DelayedAOrAn.java     |   2 +-
 src/main/java/freemarker/core/_MessageUtil.java | 355 +++++++++++++++++++
 21 files changed, 404 insertions(+), 403 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/d7c654db/src/main/java/freemarker/core/BuiltIn.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/BuiltIn.java b/src/main/java/freemarker/core/BuiltIn.java
index fa316e8..e830cb1 100644
--- a/src/main/java/freemarker/core/BuiltIn.java
+++ b/src/main/java/freemarker/core/BuiltIn.java
@@ -400,7 +400,7 @@ abstract class BuiltIn extends Expression implements Cloneable {
     
     protected final void checkMethodArgCount(int argCnt, int expectedCnt) throws TemplateModelException {
         if (argCnt != expectedCnt) {
-            throw MessageUtil.newArgCntError("?" + key, argCnt, expectedCnt);
+            throw _MessageUtil.newArgCntError("?" + key, argCnt, expectedCnt);
         }
     }
 
@@ -410,7 +410,7 @@ abstract class BuiltIn extends Expression implements Cloneable {
     
     protected final void checkMethodArgCount(int argCnt, int minCnt, int maxCnt) throws TemplateModelException {
         if (argCnt < minCnt || argCnt > maxCnt) {
-            throw MessageUtil.newArgCntError("?" + key, argCnt, minCnt, maxCnt);
+            throw _MessageUtil.newArgCntError("?" + key, argCnt, minCnt, maxCnt);
         }
     }
 
@@ -430,7 +430,7 @@ abstract class BuiltIn extends Expression implements Cloneable {
             throws TemplateModelException {
         TemplateModel arg = (TemplateModel) args.get(argIdx);
         if (!(arg instanceof TemplateScalarModel)) {
-            throw MessageUtil.newMethodArgMustBeStringException("?" + key, argIdx, arg);
+            throw _MessageUtil.newMethodArgMustBeStringException("?" + key, argIdx, arg);
         } else {
             return EvalUtil.modelToString((TemplateScalarModel) arg, null, null);
         }
@@ -443,18 +443,18 @@ abstract class BuiltIn extends Expression implements Cloneable {
             throws TemplateModelException {
         TemplateModel arg = (TemplateModel) args.get(argIdx);
         if (!(arg instanceof TemplateNumberModel)) {
-            throw MessageUtil.newMethodArgMustBeNumberException("?" + key, argIdx, arg);
+            throw _MessageUtil.newMethodArgMustBeNumberException("?" + key, argIdx, arg);
         } else {
             return EvalUtil.modelToNumber((TemplateNumberModel) arg, null);
         }
     }
     
     protected final TemplateModelException newMethodArgInvalidValueException(int argIdx, Object[] details) {
-        return MessageUtil.newMethodArgInvalidValueException("?" + key, argIdx, details);
+        return _MessageUtil.newMethodArgInvalidValueException("?" + key, argIdx, details);
     }
 
     protected final TemplateModelException newMethodArgsInvalidValueException(Object[] details) {
-        return MessageUtil.newMethodArgsInvalidValueException("?" + key, details);
+        return _MessageUtil.newMethodArgsInvalidValueException("?" + key, details);
     }
     
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/d7c654db/src/main/java/freemarker/core/BuiltInsForDates.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/BuiltInsForDates.java b/src/main/java/freemarker/core/BuiltInsForDates.java
index ec7d471..5fc0a22 100644
--- a/src/main/java/freemarker/core/BuiltInsForDates.java
+++ b/src/main/java/freemarker/core/BuiltInsForDates.java
@@ -111,7 +111,7 @@ class BuiltInsForDates {
                                 new _DelayedJQuote(tzName));
                     }
                 } else {
-                    throw MessageUtil.newMethodArgUnexpectedTypeException(
+                    throw _MessageUtil.newMethodArgUnexpectedTypeException(
                             "?" + key, 0, "string or java.util.TimeZone", tzArgTM);
                 }
                 
@@ -193,7 +193,7 @@ class BuiltInsForDates {
                 throw new _MiscTemplateException(new _ErrorDescriptionBuilder(
                             "The value of the following has unknown date type, but ?", key,
                             " needs a value where it's known if it's a date (no time part), time, or date-time value:"                        
-                        ).blame(target).tip(MessageUtil.UNKNOWN_DATE_TYPE_ERROR_TIP));
+                        ).blame(target).tip(_MessageUtil.UNKNOWN_DATE_TYPE_ERROR_TIP));
             }
         }
     

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/d7c654db/src/main/java/freemarker/core/BuiltInsForExistenceHandling.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/BuiltInsForExistenceHandling.java b/src/main/java/freemarker/core/BuiltInsForExistenceHandling.java
index f25e5dd..9e83d37 100644
--- a/src/main/java/freemarker/core/BuiltInsForExistenceHandling.java
+++ b/src/main/java/freemarker/core/BuiltInsForExistenceHandling.java
@@ -84,7 +84,7 @@ class BuiltInsForExistenceHandling {
             new TemplateMethodModelEx() {
                 public Object exec(List args) throws TemplateModelException {
                     int argCnt = args.size();
-                    if (argCnt == 0) throw MessageUtil.newArgCntError("?default", argCnt, 1, Integer.MAX_VALUE);
+                    if (argCnt == 0) throw _MessageUtil.newArgCntError("?default", argCnt, 1, Integer.MAX_VALUE);
                     for (int i = 0; i < argCnt; i++ ) {
                         TemplateModel result = (TemplateModel) args.get(i);
                         if (result != null) return result;

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/d7c654db/src/main/java/freemarker/core/BuiltInsForMultipleTypes.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/BuiltInsForMultipleTypes.java b/src/main/java/freemarker/core/BuiltInsForMultipleTypes.java
index 2adcebc..e0640c2 100644
--- a/src/main/java/freemarker/core/BuiltInsForMultipleTypes.java
+++ b/src/main/java/freemarker/core/BuiltInsForMultipleTypes.java
@@ -587,7 +587,7 @@ class BuiltInsForMultipleTypes {
                 if (cachedValue == null) {
                     if (defaultFormat == null) {
                         if (dateModel.getDateType() == TemplateDateModel.UNKNOWN) {
-                            throw MessageUtil.newCantFormatUnknownTypeDateException(target, null);
+                            throw _MessageUtil.newCantFormatUnknownTypeDateException(target, null);
                         } else {
                             throw new BugException();
                         }
@@ -596,7 +596,7 @@ class BuiltInsForMultipleTypes {
                         cachedValue = EvalUtil.assertFormatResultNotNull(defaultFormat.formatToPlainText(dateModel));
                     } catch (TemplateValueFormatException e) {
                         try {
-                            throw MessageUtil.newCantFormatDateException(defaultFormat, target, e, true);
+                            throw _MessageUtil.newCantFormatDateException(defaultFormat, target, e, true);
                         } catch (TemplateException e2) {
                             // `e` should always be a TemplateModelException here, but to be sure: 
                             throw _CoreAPI.ensureIsTemplateModelException("Failed to format date/time/datetime", e2); 

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/d7c654db/src/main/java/freemarker/core/BuiltInsForSequences.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/BuiltInsForSequences.java b/src/main/java/freemarker/core/BuiltInsForSequences.java
index f2d1c6a..a58c7f6 100644
--- a/src/main/java/freemarker/core/BuiltInsForSequences.java
+++ b/src/main/java/freemarker/core/BuiltInsForSequences.java
@@ -214,9 +214,9 @@ class BuiltInsForSequences {
                         } catch (TemplateException e) {
                             throw new _TemplateModelException(e,
                                     "\"?", key, "\" failed at index ", Integer.valueOf(idx), " with this error:\n\n",
-                                    MessageUtil.EMBEDDED_MESSAGE_BEGIN,
+                                    _MessageUtil.EMBEDDED_MESSAGE_BEGIN,
                                     new _DelayedGetMessageWithoutStackTop(e),
-                                    MessageUtil.EMBEDDED_MESSAGE_END);
+                                    _MessageUtil.EMBEDDED_MESSAGE_END);
                         }
                     }
                     idx++;
@@ -527,7 +527,7 @@ class BuiltInsForSequences {
                 // Should be:
                 // checkMethodArgCount(args, 1);
                 // But for BC:
-                if (args.size() < 1) throw MessageUtil.newArgCntError("?" + key, args.size(), 1);
+                if (args.size() < 1) throw _MessageUtil.newArgCntError("?" + key, args.size(), 1);
                 
                 String[] subvars;
                 Object obj = args.get(0);

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/d7c654db/src/main/java/freemarker/core/BuiltInsForStringsBasic.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/BuiltInsForStringsBasic.java b/src/main/java/freemarker/core/BuiltInsForStringsBasic.java
index 77f64ec..abb3530 100644
--- a/src/main/java/freemarker/core/BuiltInsForStringsBasic.java
+++ b/src/main/java/freemarker/core/BuiltInsForStringsBasic.java
@@ -604,7 +604,7 @@ class BuiltInsForStringsBasic {
                             throw newIndexGreaterThanLengthException(1, endIdx, len);
                         }
                         if (beginIdx > endIdx) {
-                            throw MessageUtil.newMethodArgsInvalidValueException("?" + key,
+                            throw _MessageUtil.newMethodArgsInvalidValueException("?" + key,
                                     "The begin index argument, ", Integer.valueOf(beginIdx),
                                     ", shouldn't be greater than the end index argument, ",
                                     Integer.valueOf(endIdx), ".");
@@ -617,7 +617,7 @@ class BuiltInsForStringsBasic {
     
                 private TemplateModelException newIndexGreaterThanLengthException(
                         int argIdx, int idx, final int len) throws TemplateModelException {
-                    return MessageUtil.newMethodArgInvalidValueException(
+                    return _MessageUtil.newMethodArgInvalidValueException(
                             "?" + key, argIdx,
                             "The index mustn't be greater than the length of the string, ",
                             Integer.valueOf(len),
@@ -626,7 +626,7 @@ class BuiltInsForStringsBasic {
     
                 private TemplateModelException newIndexLessThan0Exception(
                         int argIdx, int idx) throws TemplateModelException {
-                    return MessageUtil.newMethodArgInvalidValueException(
+                    return _MessageUtil.newMethodArgInvalidValueException(
                             "?" + key, argIdx,
                             "The index must be at least 0, but was ", Integer.valueOf(idx), ".");
                 }

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/d7c654db/src/main/java/freemarker/core/BuiltInsForStringsMisc.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/BuiltInsForStringsMisc.java b/src/main/java/freemarker/core/BuiltInsForStringsMisc.java
index 4073235..e4b18a2 100644
--- a/src/main/java/freemarker/core/BuiltInsForStringsMisc.java
+++ b/src/main/java/freemarker/core/BuiltInsForStringsMisc.java
@@ -89,9 +89,9 @@ class BuiltInsForStringsMisc {
             } catch (ParseException e) {
                 throw new _MiscTemplateException(this, env,
                         "Failed to \"?", key, "\" string with this error:\n\n",
-                        MessageUtil.EMBEDDED_MESSAGE_BEGIN,
+                        _MessageUtil.EMBEDDED_MESSAGE_BEGIN,
                         new _DelayedGetMessage(e),
-                        MessageUtil.EMBEDDED_MESSAGE_END,
+                        _MessageUtil.EMBEDDED_MESSAGE_END,
                         "\n\nThe failing expression:");
             }
             try {
@@ -99,9 +99,9 @@ class BuiltInsForStringsMisc {
             } catch (TemplateException e) {
                 throw new _MiscTemplateException(e, this, env,
                         "Failed to \"?", key, "\" string with this error:\n\n",
-                        MessageUtil.EMBEDDED_MESSAGE_BEGIN,
+                        _MessageUtil.EMBEDDED_MESSAGE_BEGIN,
                         new _DelayedGetMessageWithoutStackTop(e),
-                        MessageUtil.EMBEDDED_MESSAGE_END,
+                        _MessageUtil.EMBEDDED_MESSAGE_END,
                         "\n\nThe failing expression:");
             }
         }

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/d7c654db/src/main/java/freemarker/core/Environment.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/Environment.java b/src/main/java/freemarker/core/Environment.java
index 47b390a..cc62d4c 100644
--- a/src/main/java/freemarker/core/Environment.java
+++ b/src/main/java/freemarker/core/Environment.java
@@ -1149,7 +1149,7 @@ public final class Environment extends Configurable {
         try {
             return EvalUtil.assertFormatResultNotNull(format.formatToPlainText(number));
         } catch (TemplateValueFormatException e) {
-            throw MessageUtil.newCantFormatNumberException(format, exp, e, useTempModelExc);
+            throw _MessageUtil.newCantFormatNumberException(format, exp, e, useTempModelExc);
         }
     }
 
@@ -1424,7 +1424,7 @@ public final class Environment extends Configurable {
         try {
             return EvalUtil.assertFormatResultNotNull(format.formatToPlainText(tdm));
         } catch (TemplateValueFormatException e) {
-            throw MessageUtil.newCantFormatDateException(format, tdmSourceExpr, e, useTempModelExc);
+            throw _MessageUtil.newCantFormatDateException(format, tdmSourceExpr, e, useTempModelExc);
         }
     }
 
@@ -1447,7 +1447,7 @@ public final class Environment extends Configurable {
         try {
             return EvalUtil.assertFormatResultNotNull(format.formatToPlainText(tdm));
         } catch (TemplateValueFormatException e) {
-            throw MessageUtil.newCantFormatDateException(format, blamedDateSourceExp, e, useTempModelExc);
+            throw _MessageUtil.newCantFormatDateException(format, blamedDateSourceExp, e, useTempModelExc);
         }
     }
 
@@ -1634,7 +1634,7 @@ public final class Environment extends Configurable {
         try {
             return getTemplateDateFormat(dateType, dateClass);
         } catch (UnknownDateTypeFormattingUnsupportedException e) {
-            throw MessageUtil.newCantFormatUnknownTypeDateException(blamedDateSourceExp, e);
+            throw _MessageUtil.newCantFormatUnknownTypeDateException(blamedDateSourceExp, e);
         } catch (TemplateValueFormatException e) {
             String settingName;
             String settingValue;
@@ -1677,7 +1677,7 @@ public final class Environment extends Configurable {
         try {
             return getTemplateDateFormat(formatString, dateType, dateClass);
         } catch (UnknownDateTypeFormattingUnsupportedException e) {
-            throw MessageUtil.newCantFormatUnknownTypeDateException(blamedDateSourceExp, e);
+            throw _MessageUtil.newCantFormatUnknownTypeDateException(blamedDateSourceExp, e);
         } catch (TemplateValueFormatException e) {
             _ErrorDescriptionBuilder desc = new _ErrorDescriptionBuilder(
                     "Can't create date/time/datetime format based on format string ",
@@ -2182,15 +2182,15 @@ public final class Environment extends Configurable {
     }
 
     static void appendInstructionStackItem(TemplateElement stackEl, StringBuilder sb) {
-        sb.append(MessageUtil.shorten(stackEl.getDescription(), 40));
+        sb.append(_MessageUtil.shorten(stackEl.getDescription(), 40));
 
         sb.append("  [");
         Macro enclosingMacro = getEnclosingMacro(stackEl);
         if (enclosingMacro != null) {
-            sb.append(MessageUtil.formatLocationForEvaluationError(
+            sb.append(_MessageUtil.formatLocationForEvaluationError(
                     enclosingMacro, stackEl.beginLine, stackEl.beginColumn));
         } else {
-            sb.append(MessageUtil.formatLocationForEvaluationError(
+            sb.append(_MessageUtil.formatLocationForEvaluationError(
                     stackEl.getTemplate(), stackEl.beginLine, stackEl.beginColumn));
         }
         sb.append("]");

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/d7c654db/src/main/java/freemarker/core/EvalUtil.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/EvalUtil.java b/src/main/java/freemarker/core/EvalUtil.java
index 4b03e27..ebde9c3 100644
--- a/src/main/java/freemarker/core/EvalUtil.java
+++ b/src/main/java/freemarker/core/EvalUtil.java
@@ -373,7 +373,7 @@ class EvalUtil {
             try {
                 return assertFormatResultNotNull(format.format(tnm));
             } catch (TemplateValueFormatException e) {
-                throw MessageUtil.newCantFormatNumberException(format, exp, e, false);
+                throw _MessageUtil.newCantFormatNumberException(format, exp, e, false);
             }
         } else if (tm instanceof TemplateDateModel) {
             TemplateDateModel tdm = (TemplateDateModel) tm;
@@ -381,7 +381,7 @@ class EvalUtil {
             try {
                 return assertFormatResultNotNull(format.format(tdm));
             } catch (TemplateValueFormatException e) {
-                throw MessageUtil.newCantFormatDateException(format, exp, e, false);
+                throw _MessageUtil.newCantFormatDateException(format, exp, e, false);
             }
         } else if (tm instanceof TemplateMarkupOutputModel) {
             return tm;
@@ -408,7 +408,7 @@ class EvalUtil {
             try {
                 return ensureFormatResultString(format.format(tnm), exp, env);
             } catch (TemplateValueFormatException e) {
-                throw MessageUtil.newCantFormatNumberException(format, exp, e, false);
+                throw _MessageUtil.newCantFormatNumberException(format, exp, e, false);
             }
         } else if (tm instanceof TemplateDateModel) {
             TemplateDateModel tdm = (TemplateDateModel) tm;
@@ -416,7 +416,7 @@ class EvalUtil {
             try {
                 return ensureFormatResultString(format.format(tdm), exp, env);
             } catch (TemplateValueFormatException e) {
-                throw MessageUtil.newCantFormatDateException(format, exp, e, false);
+                throw _MessageUtil.newCantFormatDateException(format, exp, e, false);
             }
         } else { 
             return coerceModelToTextualCommon(tm, exp, seqTip, false, false, env);

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/d7c654db/src/main/java/freemarker/core/Interpret.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/Interpret.java b/src/main/java/freemarker/core/Interpret.java
index a2cff1c..7252a2f 100644
--- a/src/main/java/freemarker/core/Interpret.java
+++ b/src/main/java/freemarker/core/Interpret.java
@@ -100,9 +100,9 @@ class Interpret extends OutputFormatBoundBuiltIn {
         } catch (IOException e) {
             throw new _MiscTemplateException(this, e, env, new Object[] {
                         "Template parsing with \"?", key, "\" has failed with this error:\n\n",
-                        MessageUtil.EMBEDDED_MESSAGE_BEGIN,
+                        _MessageUtil.EMBEDDED_MESSAGE_BEGIN,
                         new _DelayedGetMessage(e),
-                        MessageUtil.EMBEDDED_MESSAGE_END,
+                        _MessageUtil.EMBEDDED_MESSAGE_END,
                         "\n\nThe failed expression:" });
         }
         
@@ -131,9 +131,9 @@ class Interpret extends OutputFormatBoundBuiltIn {
             } catch (Exception e) {
                 throw new _TemplateModelException(e,
                         "Template created with \"?", key, "\" has stopped with this error:\n\n",
-                        MessageUtil.EMBEDDED_MESSAGE_BEGIN,
+                        _MessageUtil.EMBEDDED_MESSAGE_BEGIN,
                         new _DelayedGetMessage(e),
-                        MessageUtil.EMBEDDED_MESSAGE_END);
+                        _MessageUtil.EMBEDDED_MESSAGE_END);
             }
     
             return new Writer(out)

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/d7c654db/src/main/java/freemarker/core/Macro.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/Macro.java b/src/main/java/freemarker/core/Macro.java
index fdce23b..2ea9c2c 100644
--- a/src/main/java/freemarker/core/Macro.java
+++ b/src/main/java/freemarker/core/Macro.java
@@ -119,7 +119,7 @@ public final class Macro extends TemplateElement implements TemplateModel {
                 if (function) {
                     sb.append(defaultExpr.getCanonicalForm());
                 } else {
-                    MessageUtil.appendExpressionAsUntearable(sb, defaultExpr);
+                    _MessageUtil.appendExpressionAsUntearable(sb, defaultExpr);
                 }
             }
         }

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/d7c654db/src/main/java/freemarker/core/MessageUtil.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/MessageUtil.java b/src/main/java/freemarker/core/MessageUtil.java
deleted file mode 100644
index 418ad26..0000000
--- a/src/main/java/freemarker/core/MessageUtil.java
+++ /dev/null
@@ -1,354 +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.core;
-
-import java.util.ArrayList;
-
-import freemarker.template.Template;
-import freemarker.template.TemplateException;
-import freemarker.template.TemplateModel;
-import freemarker.template.TemplateModelException;
-import freemarker.template.utility.StringUtil;
-
-/**
- * Utilities for creating error messages (and other messages).
- */
-class MessageUtil {
-
-    static final String UNKNOWN_DATE_TO_STRING_ERROR_MESSAGE
-            = "Can't convert the date-like value to string because it isn't "
-              + "known if it's a date (no time part), time or date-time value.";
-    
-    static final String UNKNOWN_DATE_PARSING_ERROR_MESSAGE
-            = "Can't parse the string to date-like value because it isn't "
-              + "known if it's desired result should be a date (no time part), a time, or a date-time value.";
-
-    static final String UNKNOWN_DATE_TYPE_ERROR_TIP = 
-            "Use ?date, ?time, or ?datetime to tell FreeMarker the exact type.";
-    
-    static final Object[] UNKNOWN_DATE_TO_STRING_TIPS = {
-            UNKNOWN_DATE_TYPE_ERROR_TIP,
-            "If you need a particular format only once, use ?string(pattern), like ?string('dd.MM.yyyy HH:mm:ss'), "
-            + "to specify which fields to display. "
-    };
-
-    static final String EMBEDDED_MESSAGE_BEGIN = "---begin-message---\n";
-
-    static final String EMBEDDED_MESSAGE_END = "\n---end-message---";
-
-    // Can't be instantiated
-    private MessageUtil() { }
-        
-    static String formatLocationForSimpleParsingError(Template template, int line, int column) {
-        return formatLocation("in", template, line, column);
-    }
-
-    static String formatLocationForSimpleParsingError(String templateSourceName, int line, int column) {
-        return formatLocation("in", templateSourceName, line, column);
-    }
-
-    static String formatLocationForDependentParsingError(Template template, int line, int column) {
-        return formatLocation("on", template, line, column);
-    }
-
-    static String formatLocationForDependentParsingError(String templateSourceName, int line, int column) {
-        return formatLocation("on", templateSourceName, line, column);
-    }
-
-    static String formatLocationForEvaluationError(Template template, int line, int column) {
-        return formatLocation("at", template, line, column);
-    }
-
-    static String formatLocationForEvaluationError(Macro macro, int line, int column) {
-        Template t = macro.getTemplate();
-        return formatLocation("at", t != null ? t.getSourceName() : null, macro.getName(), macro.isFunction(), line, column);
-    }
-    
-    static String formatLocationForEvaluationError(String templateSourceName, int line, int column) {
-        return formatLocation("at", templateSourceName, line, column);
-    }
-
-    private static String formatLocation(String preposition, Template template, int line, int column) {
-        return formatLocation(preposition, template != null ? template.getSourceName() : null, line, column);
-    }
-    
-    private static String formatLocation(String preposition, String templateSourceName, int line, int column) {
-        return formatLocation(
-                preposition, templateSourceName,
-                null, false,
-                line, column);
-    }
-
-    private static String formatLocation(
-            String preposition, String templateSourceName,
-            String macroOrFuncName, boolean isFunction,
-            int line, int column) {
-        String templateDesc;
-        if (line < 0) {
-            templateDesc = "?eval-ed string";
-            macroOrFuncName = null;
-        } else { 
-            templateDesc = templateSourceName != null
-                ? "template " + StringUtil.jQuoteNoXSS(templateSourceName)
-                : "nameless template";
-        }
-        return "in " + templateDesc
-              + (macroOrFuncName != null
-                      ? " in " + (isFunction ? "function " : "macro ") + StringUtil.jQuote(macroOrFuncName)
-                      : "")
-              + " "
-              + preposition + " " + formatPosition(line, column);
-    }
-    
-    static String formatPosition(int line, int column) {
-        return "line " + (line >= 0 ? line : line - (TemplateObject.RUNTIME_EVAL_LINE_DISPLACEMENT - 1))
-                + ", column " + column;
-    }
-
-    /**
-     * Returns a single line string that is no longer than {@code maxLength}.
-     * If will truncate the string at line-breaks too.
-     * The truncation is always signaled with a a {@code "..."} at the end of the result string.  
-     */
-    static String shorten(String s, int maxLength) {
-        if (maxLength < 5) maxLength = 5;
-        
-        boolean isTruncated = false;
-        
-        int brIdx = s.indexOf('\n');
-        if (brIdx != -1) {
-            s = s.substring(0, brIdx);
-            isTruncated = true;
-        };
-        brIdx = s.indexOf('\r');
-        if (brIdx != -1) {
-            s = s.substring(0, brIdx);
-            isTruncated = true;
-        }
-        
-        if (s.length() > maxLength) {
-            s = s.substring(0, maxLength - 3);
-            isTruncated = true;
-        }
-        
-        if (!isTruncated) {
-            return s;
-        } else {
-            if (s.endsWith(".")) {
-                if (s.endsWith("..")) {
-                    if (s.endsWith("...")) {
-                        return s;
-                    } else {
-                        return s + ".";
-                    }
-                } else {
-                    return s + "..";
-                }
-            } else {
-                return s + "...";
-            }
-        }
-    }
-    
-    static StringBuilder appendExpressionAsUntearable(StringBuilder sb, Expression argExp) {
-        boolean needParen =
-                !(argExp instanceof NumberLiteral)
-                && !(argExp instanceof StringLiteral)
-                && !(argExp instanceof BooleanLiteral)
-                && !(argExp instanceof ListLiteral)
-                && !(argExp instanceof HashLiteral)
-                && !(argExp instanceof Identifier)
-                && !(argExp instanceof Dot)
-                && !(argExp instanceof DynamicKeyName)
-                && !(argExp instanceof MethodCall)
-                && !(argExp instanceof BuiltIn)
-                && !(argExp instanceof ExistsExpression)
-                && !(argExp instanceof ParentheticalExpression);
-        if (needParen) sb.append('(');
-        sb.append(argExp.getCanonicalForm());
-        if (needParen) sb.append(')');
-        return sb;
-    }
-
-    static TemplateModelException newArgCntError(String methodName, int argCnt, int expectedCnt) {
-        return newArgCntError(methodName, argCnt, expectedCnt, expectedCnt);
-    }
-    
-    static TemplateModelException newArgCntError(String methodName, int argCnt, int minCnt, int maxCnt) {
-        ArrayList/*<Object>*/ desc = new ArrayList(20);
-        
-        desc.add(methodName);
-        
-        desc.add("(");
-        if (maxCnt != 0) desc.add("...");
-        desc.add(") expects ");
-        
-        if (minCnt == maxCnt) {
-            if (maxCnt == 0) {
-                desc.add("no");
-            } else {
-                desc.add(Integer.valueOf(maxCnt));
-            }
-        } else if (maxCnt - minCnt == 1) {
-            desc.add(Integer.valueOf(minCnt));
-            desc.add(" or ");
-            desc.add(Integer.valueOf(maxCnt));
-        } else {
-            desc.add(Integer.valueOf(minCnt));
-            if (maxCnt != Integer.MAX_VALUE) {
-                desc.add(" to ");
-                desc.add(Integer.valueOf(maxCnt));
-            } else {
-                desc.add(" or more (unlimited)");
-            }
-        }
-        desc.add(" argument");
-        if (maxCnt > 1) desc.add("s");
-        
-        desc.add(" but has received ");
-        if (argCnt == 0) {
-            desc.add("none");
-        } else {
-            desc.add(Integer.valueOf(argCnt));
-        }
-        desc.add(".");
-        
-        return new _TemplateModelException(desc.toArray());
-    }
-
-    static TemplateModelException newMethodArgMustBeStringException(String methodName, int argIdx, TemplateModel arg) {
-        return newMethodArgUnexpectedTypeException(methodName, argIdx, "string", arg);
-    }
-
-    static TemplateModelException newMethodArgMustBeNumberException(String methodName, int argIdx, TemplateModel arg) {
-        return newMethodArgUnexpectedTypeException(methodName, argIdx, "number", arg);
-    }
-    
-    static TemplateModelException newMethodArgMustBeBooleanException(String methodName, int argIdx, TemplateModel arg) {
-        return newMethodArgUnexpectedTypeException(methodName, argIdx, "boolean", arg);
-    }
-    
-    static TemplateModelException newMethodArgMustBeExtendedHashException(
-            String methodName, int argIdx, TemplateModel arg) {
-        return newMethodArgUnexpectedTypeException(methodName, argIdx, "extended hash", arg);
-    }
-    
-    static TemplateModelException newMethodArgMustBeSequenceException(
-            String methodName, int argIdx, TemplateModel arg) {
-        return newMethodArgUnexpectedTypeException(methodName, argIdx, "sequence", arg);
-    }
-    
-    static TemplateModelException newMethodArgMustBeSequenceOrCollectionException(
-            String methodName, int argIdx, TemplateModel arg) {
-        return newMethodArgUnexpectedTypeException(methodName, argIdx, "sequence or collection", arg);
-    }
-    
-    static TemplateModelException newMethodArgUnexpectedTypeException(
-            String methodName, int argIdx, String expectedType, TemplateModel arg) {
-        return new _TemplateModelException(
-                methodName, "(...) expects ", new _DelayedAOrAn(expectedType), " as argument #", Integer.valueOf(argIdx + 1),
-                ", but received ", new _DelayedAOrAn(new _DelayedFTLTypeDescription(arg)), ".");
-    }
-    
-    /**
-     * The type of the argument was good, but it's value wasn't.
-     */
-    static TemplateModelException newMethodArgInvalidValueException(
-            String methodName, int argIdx, Object... details) {
-        return new _TemplateModelException(
-                methodName, "(...) argument #", Integer.valueOf(argIdx + 1),
-                " had invalid value: ", details);
-    }
-
-    /**
-     * The type of the argument was good, but the values of two or more arguments are inconsistent with each other.
-     */
-    static TemplateModelException newMethodArgsInvalidValueException(
-            String methodName, Object... details) {
-        return new _TemplateModelException(methodName, "(...) arguments have invalid value: ", details);
-    }
-    
-    static TemplateException newInstantiatingClassNotAllowedException(String className, Environment env) {
-        return new _MiscTemplateException(env,
-                "Instantiating ", className, " is not allowed in the template for security reasons.");
-    }
-    
-    static _TemplateModelException newCantFormatUnknownTypeDateException(
-            Expression dateSourceExpr, UnknownDateTypeFormattingUnsupportedException cause) {
-        return new _TemplateModelException(cause, null, new _ErrorDescriptionBuilder(
-                MessageUtil.UNKNOWN_DATE_TO_STRING_ERROR_MESSAGE)
-                .blame(dateSourceExpr)
-                .tips(MessageUtil.UNKNOWN_DATE_TO_STRING_TIPS));
-    }
-
-    static TemplateException newCantFormatDateException(TemplateDateFormat format, Expression dataSrcExp,
-            TemplateValueFormatException e, boolean useTempModelExc) {
-        _ErrorDescriptionBuilder desc = new _ErrorDescriptionBuilder(
-                "Failed to format date/time/datetime with format ", new _DelayedJQuote(format.getDescription()), ": ",
-                e.getMessage())
-                .blame(dataSrcExp); 
-        return useTempModelExc
-                ? new _TemplateModelException(e, (Environment) null, desc)
-                : new _MiscTemplateException(e, (Environment) null, desc);
-    }
-    
-    static TemplateException newCantFormatNumberException(TemplateNumberFormat format, Expression dataSrcExp,
-            TemplateValueFormatException e, boolean useTempModelExc) {
-        _ErrorDescriptionBuilder desc = new _ErrorDescriptionBuilder(
-                "Failed to format number with format ", new _DelayedJQuote(format.getDescription()), ": ",
-                e.getMessage())
-                .blame(dataSrcExp); 
-        return useTempModelExc
-                ? new _TemplateModelException(e, (Environment) null, desc)
-                : new _MiscTemplateException(e, (Environment) null, desc);
-    }
-    
-    /**
-     * @return "a" or "an" or "a(n)" (or "" for empty string) for an FTL type name
-     */
-    static String getAOrAn(String s) {
-        if (s == null) return null;
-        if (s.length() == 0) return "";
-        
-        char fc = Character.toLowerCase(s.charAt(0));
-        if (fc == 'a' || fc == 'e' || fc == 'i') {
-            return "an";
-        } else if (fc == 'h') { 
-            String ls = s.toLowerCase();
-            if (ls.startsWith("has") || ls.startsWith("hi")) { 
-                return "a";
-            } else if (ls.startsWith("ht")) { 
-                return "an";
-            } else {
-                return "a(n)";
-            }
-        } else if (fc == 'u' || fc == 'o') {
-            return "a(n)";
-        } else {
-            char sc = (s.length() > 1) ? s.charAt(1) : '\0'; 
-            if (fc == 'x' && !(sc == 'a' || sc == 'e' || sc == 'i' || sc == 'a' || sc == 'o' || sc == 'u')) {
-                return "an";
-            } else {
-                return "a";
-            }
-        }
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/d7c654db/src/main/java/freemarker/core/ParseException.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/ParseException.java b/src/main/java/freemarker/core/ParseException.java
index 8aa5049..985c783 100644
--- a/src/main/java/freemarker/core/ParseException.java
+++ b/src/main/java/freemarker/core/ParseException.java
@@ -333,7 +333,7 @@ public class ParseException extends IOException implements FMParserConstants {
         String prefix;
         if (!isInJBossToolsMode()) {
             prefix = "Syntax error "
-                    + MessageUtil.formatLocationForSimpleParsingError(templateName, lineNumber, columnNumber)
+                    + _MessageUtil.formatLocationForSimpleParsingError(templateName, lineNumber, columnNumber)
                     + ":\n";  
         } else {
             prefix = "[col. " + columnNumber + "] ";

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/d7c654db/src/main/java/freemarker/core/TemplateClassResolver.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/TemplateClassResolver.java b/src/main/java/freemarker/core/TemplateClassResolver.java
index e02b022..67c5720 100644
--- a/src/main/java/freemarker/core/TemplateClassResolver.java
+++ b/src/main/java/freemarker/core/TemplateClassResolver.java
@@ -66,7 +66,7 @@ public interface TemplateClassResolver {
             if (className.equals(ObjectConstructor.class.getName())
                     || className.equals(Execute.class.getName())
                     || className.equals("freemarker.template.utility.JythonRuntime")) {
-                throw MessageUtil.newInstantiatingClassNotAllowedException(className, env);
+                throw _MessageUtil.newInstantiatingClassNotAllowedException(className, env);
             }
             try {
                 return ClassUtil.forName(className);
@@ -84,7 +84,7 @@ public interface TemplateClassResolver {
 
         public Class resolve(String className, Environment env, Template template)
         throws TemplateException {
-            throw MessageUtil.newInstantiatingClassNotAllowedException(className, env);
+            throw _MessageUtil.newInstantiatingClassNotAllowedException(className, env);
         }
         
     };

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/d7c654db/src/main/java/freemarker/core/TemplateObject.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/TemplateObject.java b/src/main/java/freemarker/core/TemplateObject.java
index 248395d..18355d9 100644
--- a/src/main/java/freemarker/core/TemplateObject.java
+++ b/src/main/java/freemarker/core/TemplateObject.java
@@ -98,7 +98,7 @@ public abstract class TemplateObject {
      * where in the template source, this object is.
      */
     public String getStartLocation() {
-        return MessageUtil.formatLocationForEvaluationError(template, beginLine, beginColumn);
+        return _MessageUtil.formatLocationForEvaluationError(template, beginLine, beginColumn);
     }
 
     /**
@@ -110,7 +110,7 @@ public abstract class TemplateObject {
     }
 
     public String getEndLocation() {
-        return MessageUtil.formatLocationForEvaluationError(template, endLine, endColumn);
+        return _MessageUtil.formatLocationForEvaluationError(template, endLine, endColumn);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/d7c654db/src/main/java/freemarker/core/TransformBlock.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/TransformBlock.java b/src/main/java/freemarker/core/TransformBlock.java
index 6b78fa8..78a7b87 100644
--- a/src/main/java/freemarker/core/TransformBlock.java
+++ b/src/main/java/freemarker/core/TransformBlock.java
@@ -95,7 +95,7 @@ final class TransformBlock extends TemplateElement {
                 sb.append(' ');
                 sb.append(entry.getKey());
                 sb.append('=');
-                MessageUtil.appendExpressionAsUntearable(sb, (Expression) entry.getValue());
+                _MessageUtil.appendExpressionAsUntearable(sb, (Expression) entry.getValue());
             }
         }
         if (canonical) {

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/d7c654db/src/main/java/freemarker/core/UnifiedCall.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/UnifiedCall.java b/src/main/java/freemarker/core/UnifiedCall.java
index ee0334d..f445cd3 100644
--- a/src/main/java/freemarker/core/UnifiedCall.java
+++ b/src/main/java/freemarker/core/UnifiedCall.java
@@ -116,7 +116,7 @@ final class UnifiedCall extends TemplateElement implements DirectiveCallPlace {
         StringBuilder sb = new StringBuilder();
         if (canonical) sb.append('<');
         sb.append('@');
-        MessageUtil.appendExpressionAsUntearable(sb, nameExp);
+        _MessageUtil.appendExpressionAsUntearable(sb, nameExp);
         boolean nameIsInParen = sb.charAt(sb.length() - 1) == ')';
         if (positionalArgs != null) {
             for (int i = 0; i < positionalArgs.size(); i++) {
@@ -135,7 +135,7 @@ final class UnifiedCall extends TemplateElement implements DirectiveCallPlace {
                 sb.append(' ');
                 sb.append(_CoreStringUtils.toFTLTopLevelIdentifierReference((String) entry.getKey()));
                 sb.append('=');
-                MessageUtil.appendExpressionAsUntearable(sb, argExp);
+                _MessageUtil.appendExpressionAsUntearable(sb, argExp);
             }
         }
         if (bodyParameterNames != null && !bodyParameterNames.isEmpty()) {

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/d7c654db/src/main/java/freemarker/core/UnknownDateTypeFormattingUnsupportedException.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/UnknownDateTypeFormattingUnsupportedException.java b/src/main/java/freemarker/core/UnknownDateTypeFormattingUnsupportedException.java
index 01a0871..0a4e175 100644
--- a/src/main/java/freemarker/core/UnknownDateTypeFormattingUnsupportedException.java
+++ b/src/main/java/freemarker/core/UnknownDateTypeFormattingUnsupportedException.java
@@ -29,7 +29,7 @@ import freemarker.template.TemplateDateModel;
 public final class UnknownDateTypeFormattingUnsupportedException extends UnformattableValueException {
 
     public UnknownDateTypeFormattingUnsupportedException() {
-        super(MessageUtil.UNKNOWN_DATE_TO_STRING_ERROR_MESSAGE);
+        super(_MessageUtil.UNKNOWN_DATE_TO_STRING_ERROR_MESSAGE);
     }
     
 }

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/d7c654db/src/main/java/freemarker/core/UnknownDateTypeParsingUnsupportedException.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/UnknownDateTypeParsingUnsupportedException.java b/src/main/java/freemarker/core/UnknownDateTypeParsingUnsupportedException.java
index e9edf95..2d15132 100644
--- a/src/main/java/freemarker/core/UnknownDateTypeParsingUnsupportedException.java
+++ b/src/main/java/freemarker/core/UnknownDateTypeParsingUnsupportedException.java
@@ -30,7 +30,7 @@ import freemarker.template.TemplateDateModel;
 public final class UnknownDateTypeParsingUnsupportedException extends UnformattableValueException {
 
     public UnknownDateTypeParsingUnsupportedException() {
-        super(MessageUtil.UNKNOWN_DATE_PARSING_ERROR_MESSAGE);
+        super(_MessageUtil.UNKNOWN_DATE_PARSING_ERROR_MESSAGE);
     }
     
 }

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/d7c654db/src/main/java/freemarker/core/_DelayedAOrAn.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/_DelayedAOrAn.java b/src/main/java/freemarker/core/_DelayedAOrAn.java
index 21bc896..8d7306e 100644
--- a/src/main/java/freemarker/core/_DelayedAOrAn.java
+++ b/src/main/java/freemarker/core/_DelayedAOrAn.java
@@ -29,7 +29,7 @@ public class _DelayedAOrAn extends _DelayedConversionToString {
     @Override
     protected String doConversion(Object obj) {
         String s = obj.toString();
-        return MessageUtil.getAOrAn(s) + " " + s;
+        return _MessageUtil.getAOrAn(s) + " " + s;
     }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/d7c654db/src/main/java/freemarker/core/_MessageUtil.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/_MessageUtil.java b/src/main/java/freemarker/core/_MessageUtil.java
new file mode 100644
index 0000000..a84eb9d
--- /dev/null
+++ b/src/main/java/freemarker/core/_MessageUtil.java
@@ -0,0 +1,355 @@
+/*
+ * 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.core;
+
+import java.util.ArrayList;
+
+import freemarker.template.Template;
+import freemarker.template.TemplateException;
+import freemarker.template.TemplateModel;
+import freemarker.template.TemplateModelException;
+import freemarker.template.utility.StringUtil;
+
+/**
+ * Used internally only, might changes without notice!
+ * Utilities for creating error messages (and other messages).
+ */
+public class _MessageUtil {
+
+    static final String UNKNOWN_DATE_TO_STRING_ERROR_MESSAGE
+            = "Can't convert the date-like value to string because it isn't "
+              + "known if it's a date (no time part), time or date-time value.";
+    
+    static final String UNKNOWN_DATE_PARSING_ERROR_MESSAGE
+            = "Can't parse the string to date-like value because it isn't "
+              + "known if it's desired result should be a date (no time part), a time, or a date-time value.";
+
+    static final String UNKNOWN_DATE_TYPE_ERROR_TIP = 
+            "Use ?date, ?time, or ?datetime to tell FreeMarker the exact type.";
+    
+    static final Object[] UNKNOWN_DATE_TO_STRING_TIPS = {
+            UNKNOWN_DATE_TYPE_ERROR_TIP,
+            "If you need a particular format only once, use ?string(pattern), like ?string('dd.MM.yyyy HH:mm:ss'), "
+            + "to specify which fields to display. "
+    };
+
+    static final String EMBEDDED_MESSAGE_BEGIN = "---begin-message---\n";
+
+    static final String EMBEDDED_MESSAGE_END = "\n---end-message---";
+
+    // Can't be instantiated
+    private _MessageUtil() { }
+        
+    static String formatLocationForSimpleParsingError(Template template, int line, int column) {
+        return formatLocation("in", template, line, column);
+    }
+
+    static String formatLocationForSimpleParsingError(String templateSourceName, int line, int column) {
+        return formatLocation("in", templateSourceName, line, column);
+    }
+
+    static String formatLocationForDependentParsingError(Template template, int line, int column) {
+        return formatLocation("on", template, line, column);
+    }
+
+    static String formatLocationForDependentParsingError(String templateSourceName, int line, int column) {
+        return formatLocation("on", templateSourceName, line, column);
+    }
+
+    static String formatLocationForEvaluationError(Template template, int line, int column) {
+        return formatLocation("at", template, line, column);
+    }
+
+    static String formatLocationForEvaluationError(Macro macro, int line, int column) {
+        Template t = macro.getTemplate();
+        return formatLocation("at", t != null ? t.getSourceName() : null, macro.getName(), macro.isFunction(), line, column);
+    }
+    
+    static String formatLocationForEvaluationError(String templateSourceName, int line, int column) {
+        return formatLocation("at", templateSourceName, line, column);
+    }
+
+    private static String formatLocation(String preposition, Template template, int line, int column) {
+        return formatLocation(preposition, template != null ? template.getSourceName() : null, line, column);
+    }
+    
+    private static String formatLocation(String preposition, String templateSourceName, int line, int column) {
+        return formatLocation(
+                preposition, templateSourceName,
+                null, false,
+                line, column);
+    }
+
+    private static String formatLocation(
+            String preposition, String templateSourceName,
+            String macroOrFuncName, boolean isFunction,
+            int line, int column) {
+        String templateDesc;
+        if (line < 0) {
+            templateDesc = "?eval-ed string";
+            macroOrFuncName = null;
+        } else { 
+            templateDesc = templateSourceName != null
+                ? "template " + StringUtil.jQuoteNoXSS(templateSourceName)
+                : "nameless template";
+        }
+        return "in " + templateDesc
+              + (macroOrFuncName != null
+                      ? " in " + (isFunction ? "function " : "macro ") + StringUtil.jQuote(macroOrFuncName)
+                      : "")
+              + " "
+              + preposition + " " + formatPosition(line, column);
+    }
+    
+    static String formatPosition(int line, int column) {
+        return "line " + (line >= 0 ? line : line - (TemplateObject.RUNTIME_EVAL_LINE_DISPLACEMENT - 1))
+                + ", column " + column;
+    }
+
+    /**
+     * Returns a single line string that is no longer than {@code maxLength}.
+     * If will truncate the string at line-breaks too.
+     * The truncation is always signaled with a a {@code "..."} at the end of the result string.  
+     */
+    static String shorten(String s, int maxLength) {
+        if (maxLength < 5) maxLength = 5;
+        
+        boolean isTruncated = false;
+        
+        int brIdx = s.indexOf('\n');
+        if (brIdx != -1) {
+            s = s.substring(0, brIdx);
+            isTruncated = true;
+        };
+        brIdx = s.indexOf('\r');
+        if (brIdx != -1) {
+            s = s.substring(0, brIdx);
+            isTruncated = true;
+        }
+        
+        if (s.length() > maxLength) {
+            s = s.substring(0, maxLength - 3);
+            isTruncated = true;
+        }
+        
+        if (!isTruncated) {
+            return s;
+        } else {
+            if (s.endsWith(".")) {
+                if (s.endsWith("..")) {
+                    if (s.endsWith("...")) {
+                        return s;
+                    } else {
+                        return s + ".";
+                    }
+                } else {
+                    return s + "..";
+                }
+            } else {
+                return s + "...";
+            }
+        }
+    }
+    
+    static StringBuilder appendExpressionAsUntearable(StringBuilder sb, Expression argExp) {
+        boolean needParen =
+                !(argExp instanceof NumberLiteral)
+                && !(argExp instanceof StringLiteral)
+                && !(argExp instanceof BooleanLiteral)
+                && !(argExp instanceof ListLiteral)
+                && !(argExp instanceof HashLiteral)
+                && !(argExp instanceof Identifier)
+                && !(argExp instanceof Dot)
+                && !(argExp instanceof DynamicKeyName)
+                && !(argExp instanceof MethodCall)
+                && !(argExp instanceof BuiltIn)
+                && !(argExp instanceof ExistsExpression)
+                && !(argExp instanceof ParentheticalExpression);
+        if (needParen) sb.append('(');
+        sb.append(argExp.getCanonicalForm());
+        if (needParen) sb.append(')');
+        return sb;
+    }
+
+    static TemplateModelException newArgCntError(String methodName, int argCnt, int expectedCnt) {
+        return newArgCntError(methodName, argCnt, expectedCnt, expectedCnt);
+    }
+    
+    static TemplateModelException newArgCntError(String methodName, int argCnt, int minCnt, int maxCnt) {
+        ArrayList/*<Object>*/ desc = new ArrayList(20);
+        
+        desc.add(methodName);
+        
+        desc.add("(");
+        if (maxCnt != 0) desc.add("...");
+        desc.add(") expects ");
+        
+        if (minCnt == maxCnt) {
+            if (maxCnt == 0) {
+                desc.add("no");
+            } else {
+                desc.add(Integer.valueOf(maxCnt));
+            }
+        } else if (maxCnt - minCnt == 1) {
+            desc.add(Integer.valueOf(minCnt));
+            desc.add(" or ");
+            desc.add(Integer.valueOf(maxCnt));
+        } else {
+            desc.add(Integer.valueOf(minCnt));
+            if (maxCnt != Integer.MAX_VALUE) {
+                desc.add(" to ");
+                desc.add(Integer.valueOf(maxCnt));
+            } else {
+                desc.add(" or more (unlimited)");
+            }
+        }
+        desc.add(" argument");
+        if (maxCnt > 1) desc.add("s");
+        
+        desc.add(" but has received ");
+        if (argCnt == 0) {
+            desc.add("none");
+        } else {
+            desc.add(Integer.valueOf(argCnt));
+        }
+        desc.add(".");
+        
+        return new _TemplateModelException(desc.toArray());
+    }
+
+    static TemplateModelException newMethodArgMustBeStringException(String methodName, int argIdx, TemplateModel arg) {
+        return newMethodArgUnexpectedTypeException(methodName, argIdx, "string", arg);
+    }
+
+    static TemplateModelException newMethodArgMustBeNumberException(String methodName, int argIdx, TemplateModel arg) {
+        return newMethodArgUnexpectedTypeException(methodName, argIdx, "number", arg);
+    }
+    
+    static TemplateModelException newMethodArgMustBeBooleanException(String methodName, int argIdx, TemplateModel arg) {
+        return newMethodArgUnexpectedTypeException(methodName, argIdx, "boolean", arg);
+    }
+    
+    static TemplateModelException newMethodArgMustBeExtendedHashException(
+            String methodName, int argIdx, TemplateModel arg) {
+        return newMethodArgUnexpectedTypeException(methodName, argIdx, "extended hash", arg);
+    }
+    
+    static TemplateModelException newMethodArgMustBeSequenceException(
+            String methodName, int argIdx, TemplateModel arg) {
+        return newMethodArgUnexpectedTypeException(methodName, argIdx, "sequence", arg);
+    }
+    
+    static TemplateModelException newMethodArgMustBeSequenceOrCollectionException(
+            String methodName, int argIdx, TemplateModel arg) {
+        return newMethodArgUnexpectedTypeException(methodName, argIdx, "sequence or collection", arg);
+    }
+    
+    static TemplateModelException newMethodArgUnexpectedTypeException(
+            String methodName, int argIdx, String expectedType, TemplateModel arg) {
+        return new _TemplateModelException(
+                methodName, "(...) expects ", new _DelayedAOrAn(expectedType), " as argument #", Integer.valueOf(argIdx + 1),
+                ", but received ", new _DelayedAOrAn(new _DelayedFTLTypeDescription(arg)), ".");
+    }
+    
+    /**
+     * The type of the argument was good, but it's value wasn't.
+     */
+    static TemplateModelException newMethodArgInvalidValueException(
+            String methodName, int argIdx, Object... details) {
+        return new _TemplateModelException(
+                methodName, "(...) argument #", Integer.valueOf(argIdx + 1),
+                " had invalid value: ", details);
+    }
+
+    /**
+     * The type of the argument was good, but the values of two or more arguments are inconsistent with each other.
+     */
+    static TemplateModelException newMethodArgsInvalidValueException(
+            String methodName, Object... details) {
+        return new _TemplateModelException(methodName, "(...) arguments have invalid value: ", details);
+    }
+    
+    static TemplateException newInstantiatingClassNotAllowedException(String className, Environment env) {
+        return new _MiscTemplateException(env,
+                "Instantiating ", className, " is not allowed in the template for security reasons.");
+    }
+    
+    static _TemplateModelException newCantFormatUnknownTypeDateException(
+            Expression dateSourceExpr, UnknownDateTypeFormattingUnsupportedException cause) {
+        return new _TemplateModelException(cause, null, new _ErrorDescriptionBuilder(
+                _MessageUtil.UNKNOWN_DATE_TO_STRING_ERROR_MESSAGE)
+                .blame(dateSourceExpr)
+                .tips(_MessageUtil.UNKNOWN_DATE_TO_STRING_TIPS));
+    }
+
+    static TemplateException newCantFormatDateException(TemplateDateFormat format, Expression dataSrcExp,
+            TemplateValueFormatException e, boolean useTempModelExc) {
+        _ErrorDescriptionBuilder desc = new _ErrorDescriptionBuilder(
+                "Failed to format date/time/datetime with format ", new _DelayedJQuote(format.getDescription()), ": ",
+                e.getMessage())
+                .blame(dataSrcExp); 
+        return useTempModelExc
+                ? new _TemplateModelException(e, (Environment) null, desc)
+                : new _MiscTemplateException(e, (Environment) null, desc);
+    }
+    
+    static TemplateException newCantFormatNumberException(TemplateNumberFormat format, Expression dataSrcExp,
+            TemplateValueFormatException e, boolean useTempModelExc) {
+        _ErrorDescriptionBuilder desc = new _ErrorDescriptionBuilder(
+                "Failed to format number with format ", new _DelayedJQuote(format.getDescription()), ": ",
+                e.getMessage())
+                .blame(dataSrcExp); 
+        return useTempModelExc
+                ? new _TemplateModelException(e, (Environment) null, desc)
+                : new _MiscTemplateException(e, (Environment) null, desc);
+    }
+    
+    /**
+     * @return "a" or "an" or "a(n)" (or "" for empty string) for an FTL type name
+     */
+    static String getAOrAn(String s) {
+        if (s == null) return null;
+        if (s.length() == 0) return "";
+        
+        char fc = Character.toLowerCase(s.charAt(0));
+        if (fc == 'a' || fc == 'e' || fc == 'i') {
+            return "an";
+        } else if (fc == 'h') { 
+            String ls = s.toLowerCase();
+            if (ls.startsWith("has") || ls.startsWith("hi")) { 
+                return "a";
+            } else if (ls.startsWith("ht")) { 
+                return "an";
+            } else {
+                return "a(n)";
+            }
+        } else if (fc == 'u' || fc == 'o') {
+            return "a(n)";
+        } else {
+            char sc = (s.length() > 1) ? s.charAt(1) : '\0'; 
+            if (fc == 'x' && !(sc == 'a' || sc == 'e' || sc == 'i' || sc == 'a' || sc == 'o' || sc == 'u')) {
+                return "an";
+            } else {
+                return "a";
+            }
+        }
+    }
+    
+}