freemarker-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ddek...@apache.org
Subject [06/21] incubator-freemarker git commit: Removed the legacy predefined shared variables: "html_escape", "normalize_newlines", "xml_escape", "capture_output", "compress". It had to be done now as TemplateTransformModel will be removed as part of FREEMARKE
Date Mon, 07 Aug 2017 22:32:08 GMT
Removed the legacy predefined shared variables: "html_escape", "normalize_newlines", "xml_escape", "capture_output", "compress". It had to be done now as TemplateTransformModel will be removed as part of FREEMARKER-63.


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

Branch: refs/heads/3
Commit: 1e27397dd9570ac2f48be6100afd2bba7b42b8b8
Parents: 146c425
Author: ddekany <ddekany@apache.org>
Authored: Thu Jul 27 20:45:01 2017 +0200
Committer: ddekany <ddekany@apache.org>
Committed: Thu Jul 27 20:45:01 2017 +0200

----------------------------------------------------------------------
 FM3-CHANGE-LOG.txt                              |   2 +
 .../core/TagSyntaxVariationsTest.java           |  30 ++-
 .../models/TransformHashWrapper.java            |  79 ------
 .../models/TransformMethodWrapper1.java         |  49 ----
 .../models/TransformMethodWrapper2.java         |  64 -----
 .../templatesuite/models/TransformModel1.java   | 175 --------------
 .../core/templatesuite/expected/compress.txt    |   4 -
 .../core/templatesuite/expected/newlines1.txt   |  29 ---
 .../core/templatesuite/expected/newlines2.txt   |  30 ---
 .../core/templatesuite/expected/transforms.txt  |  68 ------
 .../templatesuite/expected/type-builtins.txt    |  29 ++-
 .../core/templatesuite/templates/compress.ftl   |  17 --
 .../core/templatesuite/templates/newlines1.ftl  |  29 ---
 .../core/templatesuite/templates/newlines2.ftl  |  33 ---
 .../core/templatesuite/templates/transforms.ftl | 100 --------
 .../templatesuite/templates/type-builtins.ftl   |   5 +-
 .../freemarker/core/templatesuite/testcases.xml |   3 -
 .../apache/freemarker/core/ASTDirCompress.java  | 140 ++++++++++-
 .../apache/freemarker/core/Configuration.java   |  19 +-
 .../freemarker/core/util/CaptureOutput.java     | 147 ------------
 .../apache/freemarker/core/util/HtmlEscape.java | 109 ---------
 .../freemarker/core/util/NormalizeNewlines.java | 115 ---------
 .../freemarker/core/util/StandardCompress.java  | 239 -------------------
 .../apache/freemarker/core/util/XmlEscape.java  |  92 -------
 .../servlet/jsp/webapps/basic/customTags1.ftl   |   4 +-
 25 files changed, 183 insertions(+), 1428 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/FM3-CHANGE-LOG.txt
----------------------------------------------------------------------
diff --git a/FM3-CHANGE-LOG.txt b/FM3-CHANGE-LOG.txt
index c357c28..7943289 100644
--- a/FM3-CHANGE-LOG.txt
+++ b/FM3-CHANGE-LOG.txt
@@ -412,6 +412,8 @@ Core / Miscellaneous
   future.)
 - util.ObjectFactory was renamed to CommonSupplier, and its createObject() method was renamed to
   get(), to be more similar to the Java 8 API.
+- Removed the legacy predefined shared variables: "html_escape", "normalize_newlines", "xml_escape", "capture_output",
+  "compress"
 
 
 Build / development process changes

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core-test/src/test/java/org/apache/freemarker/core/TagSyntaxVariationsTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/TagSyntaxVariationsTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/TagSyntaxVariationsTest.java
index 536be44..02c74df 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/TagSyntaxVariationsTest.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/TagSyntaxVariationsTest.java
@@ -22,7 +22,12 @@ package org.apache.freemarker.core;
 import java.io.IOException;
 import java.io.StringReader;
 import java.io.StringWriter;
+import java.util.Collections;
+import java.util.Map;
 
+import org.apache.freemarker.core.model.TemplateDirectiveBody;
+import org.apache.freemarker.core.model.TemplateDirectiveModel;
+import org.apache.freemarker.core.model.TemplateModel;
 import org.apache.freemarker.core.util._StringUtil;
 import org.apache.freemarker.test.TestConfigurationBuilder;
 
@@ -46,9 +51,9 @@ public class TagSyntaxVariationsTest extends TestCase {
     private static final String WRONG_SQU = squarify(WRONG_ANG);
     private static final String WRONGC_ANG = "</#wrong>";
     private static final String WRONGC_SQU = squarify(WRONGC_ANG );
-    private static final String CUST_ANG = "<@compress> z </@>";
+    private static final String CUST_ANG = "<@upperCase>z</@>";
     private static final String CUST_SQU = squarify(CUST_ANG);
-    private static final String CUST_OUT = "z";
+    private static final String CUST_OUT = "Z";
     
     public TagSyntaxVariationsTest(String name) {
         super(name);
@@ -60,6 +65,9 @@ public class TagSyntaxVariationsTest extends TestCase {
 
     public final void test()
             throws TemplateException, IOException {
+        Map<String, UpperCaseDirective> sharedVariables =
+                Collections.singletonMap("upperCase", UpperCaseDirective.INSTANCE);
+
         // Permutations
         for (int ifOrAssign = 0; ifOrAssign < 2; ifOrAssign++) {
             String dir_ang = ifOrAssign == 0 ? IF_ANG : ASSIGN_ANG;
@@ -72,6 +80,7 @@ public class TagSyntaxVariationsTest extends TestCase {
                         .tagSyntax(angOrSqu == 0
                                 ? TagSyntax.ANGLE_BRACKET
                                 : TagSyntax.SQUARE_BRACKET)
+                        .sharedVariables(sharedVariables)
                         .build();
 
                 String dir_xxx = angOrSqu == 0 ? dir_ang : dir_squ;
@@ -109,6 +118,7 @@ public class TagSyntaxVariationsTest extends TestCase {
             {
                 Configuration cfg = new TestConfigurationBuilder()
                         .tagSyntax(TagSyntax.AUTO_DETECT)
+                        .sharedVariables(sharedVariables)
                         .build();
                 for (int perm = 0; perm < 4; perm++) {
                     // All 4 permutations
@@ -124,6 +134,7 @@ public class TagSyntaxVariationsTest extends TestCase {
             {
                 Configuration cfg = new TestConfigurationBuilder()
                         .tagSyntax(TagSyntax.AUTO_DETECT)
+                        .sharedVariables(sharedVariables)
                         .build();
                 // Permutations
                 for (int angOrSquStart = 0; angOrSquStart < 2; angOrSquStart++) {
@@ -183,4 +194,19 @@ public class TagSyntaxVariationsTest extends TestCase {
         assertEquals(expected, out.toString());
     }
 
+    // This will be removed when the legacy TemplateDirectiveModel is removed; the use the other UpperCaseDirective
+    // instead!
+    private static class UpperCaseDirective implements TemplateDirectiveModel {
+
+        private static final UpperCaseDirective INSTANCE = new UpperCaseDirective();
+
+        @Override
+        public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
+                throws TemplateException, IOException {
+            StringWriter sw = new StringWriter();
+            body.render(sw);
+            env.getOut().write(sw.toString().toUpperCase());
+        }
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/TransformHashWrapper.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/TransformHashWrapper.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/TransformHashWrapper.java
deleted file mode 100644
index 7771d6d..0000000
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/TransformHashWrapper.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.freemarker.core.templatesuite.models;
-
-import org.apache.freemarker.core.Configuration;
-import org.apache.freemarker.core.model.ObjectWrapper;
-import org.apache.freemarker.core.model.TemplateHashModel;
-import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.apache.freemarker.core.model.TemplateScalarModel;
-import org.apache.freemarker.core.model.impl.DefaultObjectWrapper;
-import org.apache.freemarker.core.model.impl.SimpleHash;
-import org.apache.freemarker.core.util.HtmlEscape;
-import org.apache.freemarker.core.util.StandardCompress;
-
-/**
- * Part of the TestTransform testcase suite.
- */
-public class TransformHashWrapper implements TemplateHashModel,
-        TemplateScalarModel {
-
-    private ObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
-    private SimpleHash m_cHashModel = new SimpleHash(ow);
-
-    /** Creates new TransformHashWrapper */
-    public TransformHashWrapper() {
-        m_cHashModel.put( "htmlEscape", new HtmlEscape() );
-        m_cHashModel.put( "compress", new StandardCompress() );
-        m_cHashModel.put( "escape", new TransformMethodWrapper1() );
-        m_cHashModel.put( "special", new TransformMethodWrapper2() );
-    }
-
-    /**
-     * Gets a <tt>TemplateModel</tt> from the hash.
-     *
-     * @param key the name by which the <tt>TemplateModel</tt>
-     * is identified in the template.
-     * @return the <tt>TemplateModel</tt> referred to by the key,
-     * or null if not found.
-     */
-    @Override
-    public TemplateModel get(String key) throws TemplateModelException {
-        return m_cHashModel.get( key );
-    }
-
-    /**
-     * @return true if this object is empty.
-     */
-    @Override
-    public boolean isEmpty() {
-        return false;
-    }
-
-    /**
-     * Returns the scalar's value as a String.
-     * @return the String value of this scalar.
-     */
-    @Override
-    public String getAsString() {
-        return "Utility transformations";
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/TransformMethodWrapper1.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/TransformMethodWrapper1.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/TransformMethodWrapper1.java
deleted file mode 100644
index 0fc9205..0000000
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/TransformMethodWrapper1.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.freemarker.core.templatesuite.models;
-
-import java.util.List;
-
-import org.apache.freemarker.core.model.TemplateMethodModel;
-import org.apache.freemarker.core.util.HtmlEscape;
-import org.apache.freemarker.core.util.XmlEscape;
-
-/**
- * Simple test of the interaction between MethodModels and TransformModels.
- */
-public class TransformMethodWrapper1 implements TemplateMethodModel {
-
-    /**
-     * Executes a method call.
-     *
-     * @param arguments a <tt>List</tt> of <tt>String</tt> objects containing
-     * the values of the arguments passed to the method.
-     * @return the <tt>TemplateModel</tt> produced by the method, or null.
-     */
-    @Override
-    public Object exec(List arguments) {
-
-        if (( arguments.size() > 0 ) && ( arguments.get( 0 ).toString().equals( "xml" ))) {
-            return new XmlEscape();
-        } else {
-            return new HtmlEscape();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/TransformMethodWrapper2.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/TransformMethodWrapper2.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/TransformMethodWrapper2.java
deleted file mode 100644
index 75a5b68..0000000
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/TransformMethodWrapper2.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.freemarker.core.templatesuite.models;
-
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.freemarker.core.model.TemplateMethodModel;
-
-/**
- * Another test of the interaction between MethodModels and TransformModels.
- */
-public class TransformMethodWrapper2 implements TemplateMethodModel {
-
-    /**
-     * Executes a method call.
-     *
-     * @param arguments a <tt>List</tt> of <tt>String</tt> objects containing
-     * the values of the arguments passed to the method.
-     * @return the <tt>TemplateModel</tt> produced by the method, or null.
-     */
-    @Override
-    public Object exec(List arguments) {
-        TransformModel1 cTransformer = new TransformModel1();
-        Iterator    iArgument = arguments.iterator();
-
-        // Sets up properties of the Transform model based on the arguments
-        // passed into this method
-
-        while ( iArgument.hasNext() ) {
-            String  aArgument = (String) iArgument.next();
-
-            if ( aArgument.equals( "quote" )) {
-                cTransformer.setQuotes( true );
-            } else if ( aArgument.equals( "tag" )) {
-                cTransformer.setTags( true );
-            } else if ( aArgument.equals( "ampersand" )) {
-                cTransformer.setAmpersands( true );
-            } else {
-                cTransformer.setComment( aArgument );
-            }
-        }
-
-        // Now return the transform class.
-        return cTransformer;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/TransformModel1.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/TransformModel1.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/TransformModel1.java
deleted file mode 100644
index 2fac758..0000000
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/TransformModel1.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.freemarker.core.templatesuite.models;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.util.Map;
-
-import org.apache.freemarker.core.model.TemplateTransformModel;
-
-/**
- * A TemplateTransformModel that includes properties. These properties can be
- * set at model construction time, or, for the purposes of this demonstration,
- * can be passed in from a wrapper TemplateMethodModel.
- */
-public class TransformModel1 implements TemplateTransformModel {
-
-    private boolean m_bAmpersands = false;
-    private boolean m_bQuotes = false;
-    private boolean m_bTags = false;
-    private String  m_aComment = "";
-
-    private static final int READER_BUFFER_SIZE = 4096;
-
-    @Override
-    public Writer getWriter(final Writer out,
-                            final Map args) {
-        final StringBuilder buf = new StringBuilder();
-        return new Writer(out) {
-            @Override
-            public void write(char cbuf[], int off, int len) {
-                buf.append(cbuf, off, len);
-            }
-
-            @Override
-            public void flush() {
-            }
-
-            @Override
-            public void close() throws IOException {
-                StringReader sr = new StringReader(buf.toString());
-                StringWriter sw = new StringWriter();
-                transform(sr, sw);
-                out.write(sw.toString());
-            }
-        };
-    }
-
-
-    /**
-     * Indicates whether we escape ampersands. This property can be set either
-     * while the model is being constructed, or via a property passed in through
-     * a <code>TemplateMethodModel</code>.
-     */
-    public void setAmpersands( boolean bAmpersands ) {
-        m_bAmpersands = bAmpersands;
-    }
-
-    /**
-     * Indicates whether we escape quotes. This property can be set either
-     * while the model is being constructed, or via a property passed in through
-     * a <code>TemplateMethodModel</code>.
-     */
-    public void setQuotes( boolean bQuotes ) {
-        m_bQuotes = bQuotes;
-    }
-
-    /**
-     * Indicates whether we escape tags. This property can be set either
-     * while the model is being constructed, or via a property passed in through
-     * a <code>TemplateMethodModel</code>.
-     */
-    public void setTags( boolean bTags ) {
-        m_bTags = bTags;
-    }
-
-    /**
-     * Sets a comment for this transformation. This property can be set either
-     * while the model is being constructed, or via a property passed in through
-     * a <code>TemplateMethodModel</code>.
-     */
-    public void setComment( String aComment ) {
-        m_aComment = aComment;
-    }
-
-    /**
-     * Performs a transformation/filter on FreeMarker output.
-     *
-     * @param source the input to be transformed
-     * @param output the destination of the transformation
-     */
-    public void transform(Reader source, Writer output)
-    throws IOException {
-        // Output the source, converting unsafe certain characters to their
-        // equivalent entities.
-        int n = 0;
-        boolean bCommentSent = false;
-        char[]  aBuffer = new char[ READER_BUFFER_SIZE ];
-        int i = source.read( aBuffer );
-        while (i >= 0) {
-            for ( int j = 0; j < i; j++ ) {
-                char c = aBuffer[j];
-                switch (c) {
-                    case '&':
-                        if ( m_bAmpersands ) {
-                            output.write("&amp;");
-                        } else {
-                            output.write( c );
-                        }
-                        break;
-                    case '<':
-                        if ( m_bTags ) {
-                            output.write("&lt;");
-                        } else {
-                            output.write( c );
-                        }
-                        break;
-                    case '>':
-                        if ( m_bTags ) {
-                            output.write("&gt;");
-                        } else {
-                            output.write( c );
-                        }
-                        break;
-                    case '"':
-                        if ( m_bQuotes ) {
-                            output.write("&quot;");
-                        } else {
-                            output.write( c );
-                        }
-                        break;
-                    case '\'':
-                        if ( m_bQuotes ) {
-                            output.write("&apos;");
-                        } else {
-                            output.write( c );
-                        }
-                        break;
-                    case '*':
-                        if ( ! bCommentSent ) {
-                            output.write( m_aComment );
-                            bCommentSent = true;
-                        } else {
-                            output.write( c );
-                        }
-                        break;
-                    default:
-                        output.write(c);
-                }
-                n++;
-            }
-            i = source.read( aBuffer );
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/compress.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/compress.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/compress.txt
index 43c7eed..707e299 100644
--- a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/compress.txt
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/compress.txt
@@ -28,10 +28,6 @@
 
 <p>This is the same message, using the &quot;compress&quot; tag:</p>
 <p>Hello, world!</p>
-<p>This is the same message, using the &quot;StandardCompress&quot; transform model:</p>
-<p>Hello, world!</p>
-<p>This multi-line message should be compressed to a single line.</p>
-
 <p>An example where the first character is not whitespace but the second character is:</p>
 <p>x y</p>
 

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/newlines1.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/newlines1.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/newlines1.txt
deleted file mode 100644
index bc58731..0000000
--- a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/newlines1.txt
+++ /dev/null
@@ -1,29 +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.
- */
-<html>
-<head>
-<title>FreeMarker: Newlines Test</title>
-</head>
-<body>
-<p>A simple test follows:</p>
-
-<p>Hello, world!</p>
-
-</body>
-</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/newlines2.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/newlines2.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/newlines2.txt
deleted file mode 100644
index c131421..0000000
--- a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/newlines2.txt
+++ /dev/null
@@ -1,30 +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.
- */
-<html>
-<head>
-<title>FreeMarker: Newlines the Second Test</title>
-</head>
-<body>
-<p>A simple test follows:</p>
-
-<p>Hello, world!
-</p>
-
-</body>
-</html>

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/transforms.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/transforms.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/transforms.txt
deleted file mode 100644
index 6b7f986..0000000
--- a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/transforms.txt
+++ /dev/null
@@ -1,68 +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.
- */
-<html>
-<head>
-<title>FreeMarker: Transformation Test</title>
-</head>
-<body>
-
-<p>A simple test follows:</p>
-
-<p>Hello, world!</p>
-
-&lt;p&gt;Hello, world!&lt;/p&gt;
-
-<P>Now try the Utility package:</p>
-<p>Utility transformations</p>
-
-&lt;p&gt;Utility transformations&lt;/p&gt;
-
-<p>Now some nested transforms:</p>
-<p >This tests the compress transformation</p >&lt;p &gt;This tests the compress transformation&lt;/p &gt;&lt;p &gt;This tests the compress transformation&lt;/p &gt;
-<p>Now try method and transform interactions:</p>
-&lt;p&gt;This isn&apos;t a valid XML string.&lt;/p&gt;
-&lt;p&gt;This isn't a valid HTML string.&lt;/p&gt;
-
-<p>A more advanced interaction involves getting a TemplateMethodModel
-to initialise a TemplateTransformModel, as follow:</p>
-
-Comment: This is a comment
-
-A test string containing quotes: "This isn't a test".
-A test string containing amps: Fish & Chips.
-A test string containing tags: <p>Fish &amp; Chips.</p>
-
-Comment: This is a second comment
-
-A test string containing quotes: &quot;This isn&apos;t a test&quot;.
-A test string containing amps: Fish & Chips.
-A test string containing tags: <p>Fish &amp; Chips.</p>
-Comment: This is a third comment
-
-A test string containing quotes: &quot;This isn&apos;t a test&quot;.
-A test string containing amps: Fish &amp; Chips.
-A test string containing tags: <p>Fish &amp;amp; Chips.</p>
-Comment: Utility transformations
-
-A test string containing quotes: "This isn't a test".
-A test string containing amps: Fish & Chips.
-A test string containing tags: &lt;p&gt;Fish &amp; Chips.&lt;/p&gt;
-
-</body>
-</html>

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/type-builtins.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/type-builtins.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/type-builtins.txt
index 0b4e23a..eeb191e 100644
--- a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/type-builtins.txt
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/type-builtins.txt
@@ -16,18 +16,17 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-StNuBoMeTaMaHaHxSeCoCxEnInDiNo
-1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 1 0 0 0 0 0 0 0 0 1 0
-0 0 0 0 0 1 0 0 0 0 0 0 0 1 0
-0 0 0 0 0 0 1 1 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 1 0 0 1 1 0 0
-0 0 0 0 0 0 0 0 0 1 0 1 0 0 0
-0 0 0 0 0 0 0 0 0 1 1 1 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
-1 0 0 0 0 0 1 1 0 0 0 0 0 0 0
-0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
+StNuBoMeMaHaHxSeCoCxEnInDiNo
+1 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 1 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 1 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 1 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 1 0 0 0 0 0 0 0 1 0
+0 0 0 0 0 1 1 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 1 0 0 1 1 0 0
+0 0 0 0 0 0 0 0 1 0 1 0 0 0
+0 0 0 0 0 0 0 0 1 1 1 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 1
+1 0 0 0 0 1 1 0 0 0 0 0 0 0
+0 0 0 1 0 0 0 0 0 0 0 0 0 0
+0 0 0 1 0 0 0 0 0 0 0 0 0 0

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/compress.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/compress.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/compress.ftl
index faf4ad6..2edd306 100644
--- a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/compress.ftl
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/compress.ftl
@@ -22,7 +22,6 @@
 </head>
 <body>
 
-<#assign utility={'standardCompress': "org.apache.freemarker.core.util.StandardCompress"?new()}>
 <p>A simple test follows:</p>
 
 <p>${message}</p>
@@ -35,22 +34,6 @@
 <p>${message}</p>
 </#compress>
 
-<@utility.standardCompress buffer_size=8>
-
-  <p>This is the same message,  using the &quot;StandardCompress&quot; transform model:</p>
-
-
-<p>${message}</p>
-</@>
-
-<@utility.standardCompress single_line=true>
-
-<p>This 
-   multi-line message 
-     should 
-be compressed 
-   to a single line.</p></@>
-
 <p>An example where the first character is not whitespace but the second character is:</p>
 <p><#compress>x y</#compress></p>
 

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/newlines1.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/newlines1.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/newlines1.ftl
deleted file mode 100644
index 18f4b32..0000000
--- a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/newlines1.ftl
+++ /dev/null
@@ -1,29 +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.
--->
-<html>
-<head>
-<title>FreeMarker: Newlines Test</title>
-</head>
-<body>
-<p>A simple test follows:</p>
-
-<p>${message}</p>
-
-</body>
-</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/newlines2.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/newlines2.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/newlines2.ftl
deleted file mode 100644
index ac8337c..0000000
--- a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/newlines2.ftl
+++ /dev/null
@@ -1,33 +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.
--->
-<#assign message="Hello, world!\n">
-<#assign normalizeNewlines = "org.apache.freemarker.core.util.NormalizeNewlines"?new()>
-<@normalizeNewlines>
-<html>
-<head>
-<title>FreeMarker: Newlines the Second Test</title>
-</head>
-<body>
-<p>A simple test follows:</p>
-
-<p>${message}</p>
-
-</body>
-</html>
-</@normalizeNewlines>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/transforms.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/transforms.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/transforms.ftl
deleted file mode 100644
index 9b1e55a..0000000
--- a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/transforms.ftl
+++ /dev/null
@@ -1,100 +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.
--->
-<#assign htmlEscape = "org.apache.freemarker.core.util.HtmlEscape"?new(),
-         utility = "org.apache.freemarker.core.templatesuite.models.TransformHashWrapper"?new()>
-<html>
-<head>
-<title>FreeMarker: Transformation Test</title>
-</head>
-<body>
-
-<p>A simple test follows:</p>
-
-<p>${message}</p>
-
-<@htmlEscape>
-<p>${message}</p>
-</@htmlEscape>
-
-<P>Now try the Utility package:</p>
-<p>${utility}</p>
-
-<@utility.htmlEscape>
-<p>${utility}</p>
-</@>
-
-<p>Now some nested transforms:</p>
-<@utility.compress>
-<p    >This tests the compress transformation</p >
-</@>
-<@utility.compress>
-<@utility.htmlEscape>
-<p    >This tests the compress transformation</p >
-</@>
-</@utility.compress>
-<#assign html_transform = "org.apache.freemarker.core.util.HtmlEscape"?new() />
-<@html_transform><#--Using the transform via an instantiation -->
-<@utility.compress>
-<p    >This tests the compress transformation</p >
-</@>
-</@>
-
-<p>Now try method and transform interactions:</p>
-<@utility.escape("xml")>
-<p>This isn't a valid XML string.</p>
-</@>
-<@utility.escape("html")>
-<p>This isn't a valid HTML string.</p>
-</@>
-
-<p>A more advanced interaction involves getting a TemplateMethodModel
-to initialise a TemplateTransformModel, as follow:</p>
-
-<@utility.special("This is a comment")>
-Comment: *
-
-A test string containing quotes: "This isn't a test".
-A test string containing amps: Fish & Chips.
-A test string containing tags: <p>Fish &amp; Chips.</p>
-</@>
-
-<@utility.special("This is a second comment", "quote")>
-Comment: *
-
-A test string containing quotes: "This isn't a test".
-A test string containing amps: Fish & Chips.
-A test string containing tags: <p>Fish &amp; Chips.</p>
-</@>
-<@utility.special("This is a third comment", "ampersand", "quote")>
-Comment: *
-
-A test string containing quotes: "This isn't a test".
-A test string containing amps: Fish & Chips.
-A test string containing tags: <p>Fish &amp; Chips.</p>
-</@>
-<@utility.special("tag", utility)>
-Comment: *
-
-A test string containing quotes: "This isn't a test".
-A test string containing amps: Fish & Chips.
-A test string containing tags: <p>Fish &amp; Chips.</p>
-</@>
-
-</body>
-</html>

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/type-builtins.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/type-builtins.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/type-builtins.ftl
index 3e0a942..695bd76 100644
--- a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/type-builtins.ftl
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/type-builtins.ftl
@@ -17,10 +17,10 @@
   under the License.
 -->
 <#setting booleanFormat="1,0">
-StNuBoMeTaMaHaHxSeCoCxEnInDiNo
+StNuBoMeMaHaHxSeCoCxEnInDiNo
 <#list [
   "a", 1, false,
-  testmethod, testmacro, html_escape,
+  testmethod, testmacro,
   {"a":1}, [1], testcollection, testcollectionEx,
   testnode,
   bean, bean.m, bean.mOverloaded
@@ -30,7 +30,6 @@ StNuBoMeTaMaHaHxSeCoCxEnInDiNo
   ${x?isBoolean} <#t>
   ${x?isMethod} <#t>
   ${x?isMacro} <#t>
-  ${x?isTransform} <#t>
   ${x?isHash} <#t>
   ${x?isHashEx} <#t>
   ${x?isSequence} <#t>

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/testcases.xml
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/testcases.xml b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/testcases.xml
index a02ad3c..d79ee43 100644
--- a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/testcases.xml
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/testcases.xml
@@ -121,8 +121,6 @@ Note that for the incompatibleImprovements setting you can specify a list of ver
    <testCase name="macros-return"/>
    <testCase name="multimodels"/>
    <testCase name="nested" />
-   <testCase name="newlines1" />
-   <testCase name="newlines2" />
    <testCase name="noparse" />
    <testCase name="number-format" />
    <testCase name="number-literal" >
@@ -162,7 +160,6 @@ Note that for the incompatibleImprovements setting you can specify a list of ver
    <testCase name="if" />
    <testCase name="switch" />
    <testCase name="switch-builtin" noOutput="true" />
-   <testCase name="transforms"/>
    <testCase name="type-builtins" />
    <testCase name="date-type-builtins" noOutput="true" />
    <testCase name="url" noOutput="true" />

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirCompress.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirCompress.java b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirCompress.java
index ca3fd0a..6bdda37 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirCompress.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirCompress.java
@@ -20,15 +20,12 @@
 package org.apache.freemarker.core;
 
 import java.io.IOException;
-
-import org.apache.freemarker.core.util.StandardCompress;
+import java.io.Writer;
 
 /**
  * AST directive node: {@code #compress}.
  * An instruction that reduces all sequences of whitespace to a single
  * space or newline. In addition, leading and trailing whitespace is removed.
- * 
- * @see org.apache.freemarker.core.util.StandardCompress
  */
 final class ASTDirCompress extends ASTDirective {
 
@@ -40,7 +37,12 @@ final class ASTDirCompress extends ASTDirective {
     ASTElement[] accept(Environment env) throws TemplateException, IOException {
         ASTElement[] childBuffer = getChildBuffer();
         if (childBuffer != null) {
-            env.visitAndTransform(childBuffer, StandardCompress.INSTANCE, null);
+            CompressWriter out = new CompressWriter(env.getOut(), 2048, false);
+            try {
+                env.visit(childBuffer, out);
+            } finally {
+                out.close();
+            }
         }
         return null;
     }
@@ -83,5 +85,131 @@ final class ASTDirCompress extends ASTDirective {
     boolean isNestedBlockRepeater() {
         return false;
     }
-    
+
+    // TODO [FM3] Blindly copied from FM2 StandaradCompress; review
+    private static class CompressWriter extends Writer {
+        private static final int MAX_EOL_LENGTH = 2; // CRLF is two bytes
+
+        private static final int AT_BEGINNING = 0;
+        private static final int SINGLE_LINE = 1;
+        private static final int INIT = 2;
+        private static final int SAW_CR = 3;
+        private static final int LINEBREAK_CR = 4;
+        private static final int LINEBREAK_CRLF = 5;
+        private static final int LINEBREAK_LF = 6;
+
+        private final Writer out;
+        private final char[] buf;
+        private final boolean singleLine;
+
+        private int pos = 0;
+        private boolean inWhitespace = true;
+        private int lineBreakState = AT_BEGINNING;
+
+        public CompressWriter(Writer out, int bufSize, boolean singleLine) {
+            this.out = out;
+            this.singleLine = singleLine;
+            buf = new char[bufSize];
+        }
+
+        @Override
+        public void write(char[] cbuf, int off, int len) throws IOException {
+            for (; ; ) {
+                // Need to reserve space for the EOL potentially left in the state machine
+                int room = buf.length - pos - MAX_EOL_LENGTH;
+                if (room >= len) {
+                    writeHelper(cbuf, off, len);
+                    break;
+                } else if (room <= 0) {
+                    flushInternal();
+                } else {
+                    writeHelper(cbuf, off, room);
+                    flushInternal();
+                    off += room;
+                    len -= room;
+                }
+            }
+        }
+
+        private void writeHelper(char[] cbuf, int off, int len) {
+            for (int i = off, end = off + len; i < end; i++) {
+                char c = cbuf[i];
+                if (Character.isWhitespace(c)) {
+                    inWhitespace = true;
+                    updateLineBreakState(c);
+                } else if (inWhitespace) {
+                    inWhitespace = false;
+                    writeLineBreakOrSpace();
+                    buf[pos++] = c;
+                } else {
+                    buf[pos++] = c;
+                }
+            }
+        }
+
+        /*
+          \r\n    => CRLF
+          \r[^\n] => CR
+          \r$     => CR
+          [^\r]\n => LF
+          ^\n     => LF
+        */
+        private void updateLineBreakState(char c) {
+            switch (lineBreakState) {
+                case INIT:
+                    if (c == '\r') {
+                        lineBreakState = SAW_CR;
+                    } else if (c == '\n') {
+                        lineBreakState = LINEBREAK_LF;
+                    }
+                    break;
+                case SAW_CR:
+                    if (c == '\n') {
+                        lineBreakState = LINEBREAK_CRLF;
+                    } else {
+                        lineBreakState = LINEBREAK_CR;
+                    }
+            }
+        }
+
+        private void writeLineBreakOrSpace() {
+            switch (lineBreakState) {
+                case SAW_CR:
+                    // whitespace ended with CR, fall through
+                case LINEBREAK_CR:
+                    buf[pos++] = '\r';
+                    break;
+                case LINEBREAK_CRLF:
+                    buf[pos++] = '\r';
+                    // fall through
+                case LINEBREAK_LF:
+                    buf[pos++] = '\n';
+                    break;
+                case AT_BEGINNING:
+                    // ignore leading whitespace
+                    break;
+                case INIT:
+                case SINGLE_LINE:
+                    buf[pos++] = ' ';
+            }
+            lineBreakState = (singleLine) ? SINGLE_LINE : INIT;
+        }
+
+        private void flushInternal() throws IOException {
+            out.write(buf, 0, pos);
+            pos = 0;
+        }
+
+        @Override
+        public void flush() throws IOException {
+            flushInternal();
+            out.flush();
+        }
+
+        @Override
+        public void close() throws IOException {
+            flushInternal();
+        }
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core/src/main/java/org/apache/freemarker/core/Configuration.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/Configuration.java b/freemarker-core/src/main/java/org/apache/freemarker/core/Configuration.java
index cd3a524..3eea7b9 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/Configuration.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/Configuration.java
@@ -80,11 +80,6 @@ import org.apache.freemarker.core.templateresolver.impl.DefaultTemplateNameForma
 import org.apache.freemarker.core.templateresolver.impl.DefaultTemplateResolver;
 import org.apache.freemarker.core.templateresolver.impl.MruCacheStorage;
 import org.apache.freemarker.core.templateresolver.impl.SoftCacheStorage;
-import org.apache.freemarker.core.util.CaptureOutput;
-import org.apache.freemarker.core.util.HtmlEscape;
-import org.apache.freemarker.core.util.NormalizeNewlines;
-import org.apache.freemarker.core.util.StandardCompress;
-import org.apache.freemarker.core.util.XmlEscape;
 import org.apache.freemarker.core.util._ClassUtil;
 import org.apache.freemarker.core.util._CollectionUtil;
 import org.apache.freemarker.core.util._NullArgumentException;
@@ -2304,18 +2299,6 @@ public final class Configuration implements TopLevelConfiguration, CustomStateSc
             return Collections.emptyMap();
         }
 
-        private static final Map<String, Object> DEFAULT_SHARED_VARIABLES;
-        static {
-            // TODO [FM3] Get rid of these
-            Map<String, Object> sharedVariables = new HashMap<>();
-            sharedVariables.put("capture_output", new CaptureOutput());
-            sharedVariables.put("compress", StandardCompress.INSTANCE);
-            sharedVariables.put("html_escape", new HtmlEscape());
-            sharedVariables.put("normalize_newlines", new NormalizeNewlines());
-            sharedVariables.put("xml_escape", new XmlEscape());
-            DEFAULT_SHARED_VARIABLES = Collections.unmodifiableMap(sharedVariables);
-        }
-
         /**
          * The shared variables that will be added to the built {@link Configuration} before the ones coming from
          * {@link #getSharedVariables()}. When overriding this method, always consider adding to the return value
@@ -2324,7 +2307,7 @@ public final class Configuration implements TopLevelConfiguration, CustomStateSc
          * @return Immutable {@link Map}; not {@code null}
          */
         protected Map<String, Object> getImpliedSharedVariables() {
-            return DEFAULT_SHARED_VARIABLES;
+            return Collections.emptyMap();
         }
 
         /**

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core/src/main/java/org/apache/freemarker/core/util/CaptureOutput.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/util/CaptureOutput.java b/freemarker-core/src/main/java/org/apache/freemarker/core/util/CaptureOutput.java
deleted file mode 100644
index 93109e0..0000000
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/util/CaptureOutput.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.freemarker.core.util;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.Map;
-
-import org.apache.freemarker.core.Environment;
-import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.apache.freemarker.core.model.TemplateScalarModel;
-import org.apache.freemarker.core.model.TemplateTransformModel;
-import org.apache.freemarker.core.model.impl.SimpleScalar;
-
-/**
- * A transform that captures the output of a block of FTL code and stores that in a variable.
- *
- * <p>As this transform is initially present in the shared variable set, you can always
- * access it from the templates:</p>
- *
- * <pre>
- * &lt;@capture_output var="captured"&gt;
- *   ...
- * &lt;/@capture_output&gt;
- * </pre>
- *
- * <p>And later in the template you can use the captured output:</p>
- *
- * ${captured}
- *
- * <p>This transform requires one of three parameters: <code>var</code>, <code>local</code>, or <code>global</code>.
- * Each of them specifies the name of the variable that stores the captured output, but the first creates a
- * variable in a name-space (as &lt;#assign&gt;), the second creates a macro-local variable (as &lt;#local&gt;),
- * and the last creates a global variable (as &lt;#global&gt;).
- * </p>
- * <p>In the case of an assignment within a namespace, there is an optional parameter
- * <code>namespace</code> that indicates in which namespace to do the assignment.
- * if this is omitted, the current namespace is used, and this will be, by far, the most
- * common usage pattern.</p>
- *
- * @deprecated Use block-assignments instead, like <code>&lt;assign x&gt;...&lt;/assign&gt;</code>.
- */
-@Deprecated
-public class CaptureOutput implements TemplateTransformModel {
-
-    @Override
-    public Writer getWriter(final Writer out, final Map args) throws TemplateModelException {
-        String errmsg = "Must specify the name of the variable in "
-                + "which to capture the output with the 'var' or 'local' or 'global' parameter.";
-        if (args == null) throw new TemplateModelException(errmsg);
-
-        boolean local = false, global = false;
-        final TemplateModel nsModel = (TemplateModel) args.get("namespace");
-        Object varNameModel = args.get("var");
-        if (varNameModel == null) {
-            varNameModel = args.get("local");
-            if (varNameModel == null) {
-                varNameModel = args.get("global");
-                global = true;
-            } else {
-                local = true;
-            }
-            if (varNameModel == null) {
-                throw new TemplateModelException(errmsg);
-            }
-        }
-        if (args.size() == 2) {
-            if (nsModel == null) {
-                throw new TemplateModelException("Second parameter can only be namespace");
-            }
-            if (local) {
-                throw new TemplateModelException("Cannot specify namespace for a local assignment");
-            }
-            if (global) {
-                throw new TemplateModelException("Cannot specify namespace for a global assignment");
-            }
-            if (!(nsModel instanceof Environment.Namespace)) {
-                throw new TemplateModelException("namespace parameter does not specify a namespace. It is a " + nsModel.getClass().getName());
-            }
-        } else if (args.size() != 1) throw new TemplateModelException(
-                "Bad parameters. Use only one of 'var' or 'local' or 'global' parameters.");
-
-        if (!(varNameModel instanceof TemplateScalarModel)) {
-            throw new TemplateModelException("'var' or 'local' or 'global' parameter doesn't evaluate to a string");
-        }
-        final String varName = ((TemplateScalarModel) varNameModel).getAsString();
-        if (varName == null) {
-            throw new TemplateModelException("'var' or 'local' or 'global' parameter evaluates to null string");
-        }
-
-        final StringBuilder buf = new StringBuilder();
-        final Environment env = Environment.getCurrentEnvironment();
-        final boolean localVar = local;
-        final boolean globalVar = global;
-
-        return new Writer() {
-
-            @Override
-            public void write(char cbuf[], int off, int len) {
-                buf.append(cbuf, off, len);
-            }
-
-            @Override
-            public void flush() throws IOException {
-                out.flush();
-            }
-
-            @Override
-            public void close() throws IOException {
-                SimpleScalar result = new SimpleScalar(buf.toString());
-                try {
-                    if (localVar) {
-                        env.setLocalVariable(varName, result);
-                    } else if (globalVar) {
-                        env.setGlobalVariable(varName, result);
-                    } else {
-                        if (nsModel == null) {
-                            env.setVariable(varName, result);
-                        } else {
-                            ((Environment.Namespace) nsModel).put(varName, result);
-                        }
-                    }
-                } catch (java.lang.IllegalStateException ise) { // if somebody uses 'local' outside a macro
-                    throw new IOException("Could not set variable " + varName + ": " + ise.getMessage());
-                }
-            }
-        };
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core/src/main/java/org/apache/freemarker/core/util/HtmlEscape.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/util/HtmlEscape.java b/freemarker-core/src/main/java/org/apache/freemarker/core/util/HtmlEscape.java
deleted file mode 100644
index 3aa8d1d..0000000
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/util/HtmlEscape.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.freemarker.core.util;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.Map;
-
-import org.apache.freemarker.core.model.TemplateTransformModel;
-
-/**
- * Performs an HTML escape of a given template fragment. Specifically,
- * &lt; &gt; &quot; and &amp; are all turned into entities.
- *
- * <p>Usage:<br>
- * From java:</p>
- * <pre>
- * SimpleHash root = new SimpleHash();
- *
- * root.put( "htmlEscape", new org.apache.freemarker.core.util.HtmlEscape() );
- *
- * ...
- * </pre>
- *
- * <p>From your FreeMarker template:</p>
- * <pre>
- *
- * The following is HTML-escaped:
- * &lt;transform htmlEscape&gt;
- *   &lt;p&gt;This paragraph has all HTML special characters escaped.&lt;/p&gt;
- * &lt;/transform&gt;
- *
- * ...
- * </pre>
- *
- * @see org.apache.freemarker.core.util.XmlEscape
- */
-// [FM3] Remove (or move to o.a.f.test)
-public class HtmlEscape implements TemplateTransformModel {
-
-    private static final char[] LT = "&lt;".toCharArray();
-    private static final char[] GT = "&gt;".toCharArray();
-    private static final char[] AMP = "&amp;".toCharArray();
-    private static final char[] QUOT = "&quot;".toCharArray();
-
-    @Override
-    public Writer getWriter(final Writer out, Map args) {
-        return new Writer()
-        {
-            @Override
-            public void write(int c)
-            throws IOException {
-                switch(c)
-                {
-                    case '<': out.write(LT, 0, 4); break;
-                    case '>': out.write(GT, 0, 4); break;
-                    case '&': out.write(AMP, 0, 5); break;
-                    case '"': out.write(QUOT, 0, 6); break;
-                    default: out.write(c);
-                }
-            }
-
-            @Override
-            public void write(char cbuf[], int off, int len)
-            throws IOException {
-                int lastoff = off;
-                int lastpos = off + len;
-                for (int i = off; i < lastpos; i++) {
-                    switch (cbuf[i])
-                    {
-                        case '<': out.write(cbuf, lastoff, i - lastoff); out.write(LT, 0, 4); lastoff = i + 1; break;
-                        case '>': out.write(cbuf, lastoff, i - lastoff); out.write(GT, 0, 4); lastoff = i + 1; break;
-                        case '&': out.write(cbuf, lastoff, i - lastoff); out.write(AMP, 0, 5); lastoff = i + 1; break;
-                        case '"': out.write(cbuf, lastoff, i - lastoff); out.write(QUOT, 0, 6); lastoff = i + 1; break;
-                    }
-                }
-                int remaining = lastpos - lastoff;
-                if (remaining > 0) {
-                    out.write(cbuf, lastoff, remaining);
-                }
-            }
-            @Override
-            public void flush() throws IOException {
-                out.flush();
-            }
-
-            @Override
-            public void close() {
-            }
-        };
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core/src/main/java/org/apache/freemarker/core/util/NormalizeNewlines.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/util/NormalizeNewlines.java b/freemarker-core/src/main/java/org/apache/freemarker/core/util/NormalizeNewlines.java
deleted file mode 100644
index f4bc5a6..0000000
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/util/NormalizeNewlines.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.freemarker.core.util;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.Reader;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.util.Map;
-
-import org.apache.freemarker.core.model.TemplateTransformModel;
-
-/**
- * <p>Transformer that supports FreeMarker legacy behavior: all newlines appearing
- * within the transformed area will be transformed into the platform's default
- * newline. Unlike the old behavior, however, newlines generated by the data
- * model are also converted. Legacy behavior was to leave newlines in the
- * data model unaltered.</p>
- *
- * <p>Usage:<br>
- * From java:</p>
- * <pre>
- * SimpleHash root = new SimpleHash();
- *
- * root.put( "normalizeNewlines", new org.apache.freemarker.core.util.NormalizeNewlines() );
- *
- * ...
- * </pre>
- *
- * <p>From your FreeMarker template:</p>
- * <pre>
- * &lt;transform normalizeNewlines&gt;
- *   &lt;html&gt;
- *   &lt;head&gt;
- *   ...
- *   &lt;p&gt;This template has all newlines normalized to the current platform's
- *   default.&lt;/p&gt;
- *   ...
- *   &lt;/body&gt;
- *   &lt;/html&gt;
- * &lt;/transform&gt;
- * </pre>
- */
-// [FM3] Remove (or move to o.a.f.test)
-public class NormalizeNewlines implements TemplateTransformModel {
-
-    @Override
-    public Writer getWriter(final Writer out,
-                            final Map args) {
-        final StringBuilder buf = new StringBuilder();
-        return new Writer() {
-            @Override
-            public void write(char cbuf[], int off, int len) {
-                buf.append(cbuf, off, len);
-            }
-
-            @Override
-            public void flush() throws IOException {
-                out.flush();
-            }
-
-            @Override
-            public void close() throws IOException {
-                StringReader sr = new StringReader(buf.toString());
-                StringWriter sw = new StringWriter();
-                transform(sr, sw);
-                out.write(sw.toString());
-            }
-        };
-    }
-
-    /**
-     * Performs newline normalization on FreeMarker output.
-     *
-     * @param in the input to be transformed
-     * @param out the destination of the transformation
-     */
-    public void transform(Reader in, Writer out) throws IOException {
-        BufferedReader br = (in instanceof BufferedReader)
-                            ? (BufferedReader) in
-                            : new BufferedReader(in);
-        PrintWriter pw = (out instanceof PrintWriter)
-                         ? (PrintWriter) out
-                         : new PrintWriter(out);
-        String line = br.readLine();
-        if (line != null) {
-            if ( line.length() > 0 ) {
-                pw.println(line);
-            }
-        }
-        while ((line = br.readLine()) != null) {
-            pw.println(line);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core/src/main/java/org/apache/freemarker/core/util/StandardCompress.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/util/StandardCompress.java b/freemarker-core/src/main/java/org/apache/freemarker/core/util/StandardCompress.java
deleted file mode 100644
index 0943622..0000000
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/util/StandardCompress.java
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.freemarker.core.util;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.Map;
-
-import org.apache.freemarker.core.model.TemplateBooleanModel;
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.apache.freemarker.core.model.TemplateNumberModel;
-import org.apache.freemarker.core.model.TemplateTransformModel;
-
-/**
- * <p>A filter that compresses each sequence of consecutive whitespace
- * to a single line break (if the sequence contains a line break) or a
- * single space. In addition, leading and trailing whitespace is
- * completely removed.</p>
- * 
- * <p>Specify the transform parameter <code>single_line = true</code>
- * to always compress to a single space instead of a line break.</p>
- * 
- * <p>The default buffer size can be overridden by specifying a
- * <code>buffer_size</code> transform parameter (in bytes).</p>
- *
- * <p><b>Note:</b> The compress tag is implemented using this filter</p>
- * 
- * <p>Usage:<br>
- * From java:</p>
- * <pre>
- * SimpleHash root = new SimpleHash();
- *
- * root.put( "standardCompress", new org.apache.freemarker.core.util.StandardCompress() );
- *
- * ...
- * </pre>
- *
- * <p>From your FreeMarker template:</p>
- * <pre>
- * &lt;transform standardCompress&gt;
- *   &lt;p&gt;This    paragraph will have
- *       extraneous
- *
- * whitespace removed.&lt;/p&gt;
- * &lt;/transform&gt;
- * </pre>
- *
- * <p>Output:</p>
- * <pre>
- * &lt;p&gt;This paragraph will have
- * extraneous
- * whitespace removed.&lt;/p&gt;
- * </pre>
- */
-// [FM3] Remove (or move to o.a.f.test), instead extend #compress
-public class StandardCompress implements TemplateTransformModel {
-    private static final String BUFFER_SIZE_KEY = "buffer_size";
-    private static final String SINGLE_LINE_KEY = "single_line";
-    private int defaultBufferSize;
-
-    public static final StandardCompress INSTANCE = new StandardCompress();
-    
-    public StandardCompress() {
-        this(2048);
-    }
-
-    /**
-     * @param defaultBufferSize the default amount of characters to buffer
-     */
-    public StandardCompress(int defaultBufferSize) {
-        this.defaultBufferSize = defaultBufferSize;
-    }
-
-    @Override
-    public Writer getWriter(final Writer out, Map args)
-    throws TemplateModelException {
-        int bufferSize = defaultBufferSize;
-        boolean singleLine = false;
-        if (args != null) {
-            try {
-                TemplateNumberModel num = (TemplateNumberModel) args.get(BUFFER_SIZE_KEY);
-                if (num != null)
-                    bufferSize = num.getAsNumber().intValue();
-            } catch (ClassCastException e) {
-                throw new TemplateModelException("Expecting numerical argument to " + BUFFER_SIZE_KEY);
-            }
-            try {
-                TemplateBooleanModel flag = (TemplateBooleanModel) args.get(SINGLE_LINE_KEY);
-                if (flag != null)
-                    singleLine = flag.getAsBoolean();
-            } catch (ClassCastException e) {
-                throw new TemplateModelException("Expecting boolean argument to " + SINGLE_LINE_KEY);
-            }
-        }
-        return new StandardCompressWriter(out, bufferSize, singleLine);
-    }
-
-    private static class StandardCompressWriter extends Writer {
-        private static final int MAX_EOL_LENGTH = 2; // CRLF is two bytes
-        
-        private static final int AT_BEGINNING = 0;
-        private static final int SINGLE_LINE = 1;
-        private static final int INIT = 2;
-        private static final int SAW_CR = 3;
-        private static final int LINEBREAK_CR = 4;
-        private static final int LINEBREAK_CRLF = 5;
-        private static final int LINEBREAK_LF = 6;
-
-        private final Writer out;
-        private final char[] buf;
-        private final boolean singleLine;
-    
-        private int pos = 0;
-        private boolean inWhitespace = true;
-        private int lineBreakState = AT_BEGINNING;
-
-        public StandardCompressWriter(Writer out, int bufSize, boolean singleLine) {
-            this.out = out;
-            this.singleLine = singleLine;
-            buf = new char[bufSize];
-        }
-
-        @Override
-        public void write(char[] cbuf, int off, int len) throws IOException {
-            for (; ; ) {
-                // Need to reserve space for the EOL potentially left in the state machine
-                int room = buf.length - pos - MAX_EOL_LENGTH; 
-                if (room >= len) {
-                    writeHelper(cbuf, off, len);
-                    break;
-                } else if (room <= 0) {
-                    flushInternal();
-                } else {
-                    writeHelper(cbuf, off, room);
-                    flushInternal();
-                    off += room;
-                    len -= room;
-                }
-            }
-        }
-
-        private void writeHelper(char[] cbuf, int off, int len) {
-            for (int i = off, end = off + len; i < end; i++) {
-                char c = cbuf[i];
-                if (Character.isWhitespace(c)) {
-                    inWhitespace = true;
-                    updateLineBreakState(c);
-                } else if (inWhitespace) {
-                    inWhitespace = false;
-                    writeLineBreakOrSpace();
-                    buf[pos++] = c;
-                } else {
-                    buf[pos++] = c;
-                }
-            }
-        }
-
-        /*
-          \r\n    => CRLF
-          \r[^\n] => CR
-          \r$     => CR
-          [^\r]\n => LF
-          ^\n     => LF
-        */
-        private void updateLineBreakState(char c) {
-            switch (lineBreakState) {
-            case INIT:
-                if (c == '\r') {
-                    lineBreakState = SAW_CR;
-                } else if (c == '\n') {
-                    lineBreakState = LINEBREAK_LF;
-                }
-                break;
-            case SAW_CR:
-                if (c == '\n') {
-                    lineBreakState = LINEBREAK_CRLF;
-                } else {
-                    lineBreakState = LINEBREAK_CR;
-                }
-            }
-        }
-
-        private void writeLineBreakOrSpace() {
-            switch (lineBreakState) {
-            case SAW_CR:
-                // whitespace ended with CR, fall through
-            case LINEBREAK_CR:
-                buf[pos++] = '\r';
-                break;
-            case LINEBREAK_CRLF:
-                buf[pos++] = '\r';
-                // fall through
-            case LINEBREAK_LF:
-                buf[pos++] = '\n';
-                break;
-            case AT_BEGINNING:
-                // ignore leading whitespace
-                break;
-            case INIT:
-            case SINGLE_LINE:
-                buf[pos++] = ' ';
-            }
-            lineBreakState = (singleLine) ? SINGLE_LINE : INIT;
-        }
-
-        private void flushInternal() throws IOException {
-            out.write(buf, 0, pos);
-            pos = 0;
-        }
-
-        @Override
-        public void flush() throws IOException {
-            flushInternal();
-            out.flush();
-        }
-
-        @Override
-        public void close() throws IOException {
-            flushInternal();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-core/src/main/java/org/apache/freemarker/core/util/XmlEscape.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/util/XmlEscape.java b/freemarker-core/src/main/java/org/apache/freemarker/core/util/XmlEscape.java
deleted file mode 100644
index 43a2344..0000000
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/util/XmlEscape.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.freemarker.core.util;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.Map;
-
-import org.apache.freemarker.core.model.TemplateTransformModel;
-
-/**
- * Performs an XML escaping of a given template fragment. Specifically,
- * <tt>&lt;</tt> <tt>&gt;</tt> <tt>&quot;</tt> <tt>'</tt> and <tt>&amp;</tt> are all turned into entity references.
- *
- * <p>An instance of this transform is initially visible as shared
- * variable called <tt>xml_escape</tt>.</p>
- */
-// [FM3] Remove (or move to o.a.f.test)
-public class XmlEscape implements TemplateTransformModel {
-
-    private static final char[] LT = "&lt;".toCharArray();
-    private static final char[] GT = "&gt;".toCharArray();
-    private static final char[] AMP = "&amp;".toCharArray();
-    private static final char[] QUOT = "&quot;".toCharArray();
-    private static final char[] APOS = "&apos;".toCharArray();
-
-    @Override
-    public Writer getWriter(final Writer out, Map args) {
-        return new Writer()
-        {
-            @Override
-            public void write(int c)
-            throws IOException {
-                switch(c)
-                {
-                    case '<': out.write(LT, 0, 4); break;
-                    case '>': out.write(GT, 0, 4); break;
-                    case '&': out.write(AMP, 0, 5); break;
-                    case '"': out.write(QUOT, 0, 6); break;
-                    case '\'': out.write(APOS, 0, 6); break;
-                    default: out.write(c);
-                }
-            }
-
-            @Override
-            public void write(char cbuf[], int off, int len)
-            throws IOException {
-                int lastoff = off;
-                int lastpos = off + len;
-                for (int i = off; i < lastpos; i++) {
-                    switch (cbuf[i])
-                    {
-                        case '<': out.write(cbuf, lastoff, i - lastoff); out.write(LT, 0, 4); lastoff = i + 1; break;
-                        case '>': out.write(cbuf, lastoff, i - lastoff); out.write(GT, 0, 4); lastoff = i + 1; break;
-                        case '&': out.write(cbuf, lastoff, i - lastoff); out.write(AMP, 0, 5); lastoff = i + 1; break;
-                        case '"': out.write(cbuf, lastoff, i - lastoff); out.write(QUOT, 0, 6); lastoff = i + 1; break;
-                        case '\'': out.write(cbuf, lastoff, i - lastoff); out.write(APOS, 0, 6); lastoff = i + 1; break;
-                    }
-                }
-                int remaining = lastpos - lastoff;
-                if (remaining > 0) {
-                    out.write(cbuf, lastoff, remaining);
-                }
-            }
-            @Override
-            public void flush() throws IOException {
-                out.flush();
-            }
-
-            @Override
-            public void close() {
-            }
-        };
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e27397d/freemarker-servlet/src/test/resources/org/apache/freemarker/servlet/jsp/webapps/basic/customTags1.ftl
----------------------------------------------------------------------
diff --git a/freemarker-servlet/src/test/resources/org/apache/freemarker/servlet/jsp/webapps/basic/customTags1.ftl b/freemarker-servlet/src/test/resources/org/apache/freemarker/servlet/jsp/webapps/basic/customTags1.ftl
index 9334853..0f029b4 100644
--- a/freemarker-servlet/src/test/resources/org/apache/freemarker/servlet/jsp/webapps/basic/customTags1.ftl
+++ b/freemarker-servlet/src/test/resources/org/apache/freemarker/servlet/jsp/webapps/basic/customTags1.ftl
@@ -44,11 +44,11 @@
 <!-- Test nested execution with intermittent non-JSP transform -->
 <@t.testtag repeatCount=2 throwException=false>
 Outer Blah
-<@compress>
+<#compress>
 <@t.testtag repeatCount=2 throwException=false>
 Inner Blah
 </@>
-</@>
+</#compress>
 </@>
 
 <@t.simpletag bodyLoopCount=2 name="simpletag1">


Mime
View raw message