You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2017/12/20 00:56:00 UTC

[03/49] groovy git commit: Move source files to proper packages

http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/util/GroovyCollections.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/util/GroovyCollections.java b/src/main/groovy/util/GroovyCollections.java
deleted file mode 100644
index dff062d..0000000
--- a/src/main/groovy/util/GroovyCollections.java
+++ /dev/null
@@ -1,293 +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 groovy.util;
-
-import org.codehaus.groovy.runtime.DefaultGroovyMethods;
-import org.codehaus.groovy.runtime.ScriptBytecodeAdapter;
-import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * A Collections utility class
- *
- * @author Paul King
- * @author Jim White
- */
-public class GroovyCollections {
-    /**
-     * Finds all combinations of items from the given collections.
-     *
-     * @param collections the given collections
-     * @return a List of the combinations found
-     * @see #combinations(Collection)
-     */
-    public static List combinations(Object[] collections) {
-        return combinations((Iterable)Arrays.asList(collections));
-    }
-
-    /**
-     * Finds all non-null subsequences of a list.
-     * E.g. <code>subsequences([1, 2, 3])</code> would be:
-     * [[1, 2, 3], [1, 3], [2, 3], [1, 2], [1], [2], [3]]
-     *
-     * @param items the List of items
-     * @return the subsequences from items
-     */
-    public static <T> Set<List<T>> subsequences(List<T> items) {
-        // items.inject([]){ ss, h -> ss.collect { it + [h] }  + ss + [[h]] }
-        Set<List<T>> ans = new HashSet<List<T>>();
-        for (T h : items) {
-            Set<List<T>> next = new HashSet<List<T>>();
-            for (List<T> it : ans) {
-                List<T> sublist = new ArrayList<T>(it);
-                sublist.add(h);
-                next.add(sublist);
-            }
-            next.addAll(ans);
-            List<T> hlist = new ArrayList<T>();
-            hlist.add(h);
-            next.add(hlist);
-            ans = next;
-        }
-        return ans;
-    }
-
-    /**
-     * @param collections the given collections
-     * @deprecated use combinations(Iterable)
-     */
-    @Deprecated
-    public static List combinations(Collection collections) {
-        return combinations((Iterable)collections);
-    }
-
-    /**
-     * Finds all combinations of items from the given Iterable aggregate of collections.
-     * So, <code>combinations([[true, false], [true, false]])</code>
-     * is <code>[[true, true], [false, true], [true, false], [false, false]]</code>
-     * and <code>combinations([['a', 'b'],[1, 2, 3]])</code>
-     * is <code>[['a', 1], ['b', 1], ['a', 2], ['b', 2], ['a', 3], ['b', 3]]</code>.
-     * If a non-collection item is given, it is treated as a singleton collection,
-     * i.e. <code>combinations([[1, 2], 'x'])</code> is <code>[[1, 'x'], [2, 'x']]</code>.
-     *
-     * @param collections the Iterable of given collections
-     * @return a List of the combinations found
-     * @since 2.2.0
-     */
-    public static List combinations(Iterable collections) {
-        List collectedCombos = new ArrayList();
-        for (Object collection : collections) {
-            Iterable items = DefaultTypeTransformation.asCollection(collection);
-            if (collectedCombos.isEmpty()) {
-                for (Object item : items) {
-                    List l = new ArrayList();
-                    l.add(item);
-                    collectedCombos.add(l);
-                }
-            } else {
-                List savedCombos = new ArrayList(collectedCombos);
-                List newCombos = new ArrayList();
-                for (Object value : items) {
-                    for (Object savedCombo : savedCombos) {
-                        List oldList = new ArrayList((List) savedCombo);
-                        oldList.add(value);
-                        newCombos.add(oldList);
-                    }
-                }
-                collectedCombos = newCombos;
-            }
-        }
-        return collectedCombos;
-    }
-
-    public static <T> List<List<T>> inits(Iterable<T> collections) {
-        List<T> copy = DefaultGroovyMethods.toList(collections);
-        List<List<T>> result = new ArrayList<List<T>>();
-        for (int i = copy.size(); i >= 0; i--) {
-            List<T> next = copy.subList(0, i);
-            result.add(next);
-        }
-        return result;
-    }
-
-    public static <T> List<List<T>> tails(Iterable<T> collections) {
-        List<T> copy = DefaultGroovyMethods.toList(collections);
-        List<List<T>> result = new ArrayList<List<T>>();
-        for (int i = 0; i <= copy.size(); i++) {
-            List<T> next = copy.subList(i, copy.size());
-            result.add(next);
-        }
-        return result;
-    }
-
-    /**
-     * Transposes an array of lists.
-     *
-     * @param lists the given lists
-     * @return a List of the transposed lists
-     * @see #transpose(List)
-     */
-    public static List transpose(Object[] lists) {
-        return transpose(Arrays.asList(lists));
-    }
-
-    /**
-     * Transposes the given lists.
-     * So, <code>transpose([['a', 'b'], [1, 2]])</code>
-     * is <code>[['a', 1], ['b', 2]]</code> and
-     * <code>transpose([['a', 'b', 'c']])</code>
-     * is <code>[['a'], ['b'], ['c']]</code>.
-     *
-     * @param lists the given lists
-     * @return a List of the transposed lists
-     */
-    public static List transpose(List lists) {
-        List result = new ArrayList();
-        if (lists.isEmpty()) return result;
-        int minSize = Integer.MAX_VALUE;
-        for (Object listLike : lists) {
-            List list = (List) DefaultTypeTransformation.castToType(listLike, List.class);
-            if (list.size() < minSize) minSize = list.size();
-        }
-        if (minSize == 0) return result;
-        for (int i = 0; i < minSize; i++) {
-            result.add(new ArrayList());
-        }
-        for (Object listLike : lists) {
-            List list = (List) DefaultTypeTransformation.castToType(listLike, List.class);
-            for (int i = 0; i < minSize; i++) {
-                List resultList = (List) result.get(i);
-                resultList.add(list.get(i));
-            }
-        }
-        return result;
-    }
-
-    /**
-     * Selects the minimum value found in an array of items, so
-     * min([2, 4, 6] as Object[]) == 2.
-     *
-     * @param items an array of items
-     * @return the minimum value
-     */
-    public static <T> T min(T[] items) {
-        return min((Iterable<T>)Arrays.asList(items));
-    }
-
-    /**
-     * @deprecated use min(Iterable)
-     */
-    @Deprecated
-    public static <T> T min(Collection<T> items) {
-        return min((Iterable<T>)items);
-    }
-
-    /**
-     * Selects the minimum value found in an Iterable of items.
-     *
-     * @param items an Iterable
-     * @return the minimum value
-     * @since 2.2.0
-     */
-    public static <T> T min(Iterable<T> items) {
-        T answer = null;
-        for (T value : items) {
-            if (value != null) {
-                if (answer == null || ScriptBytecodeAdapter.compareLessThan(value, answer)) {
-                    answer = value;
-                }
-            }
-        }
-        return answer;
-    }
-
-    /**
-     * Selects the maximum value found in an array of items, so
-     * min([2, 4, 6] as Object[]) == 6.
-     *
-     * @param items an array of items
-     * @return the maximum value
-     */
-    public static <T> T max(T[] items) {
-        return max((Iterable<T>)Arrays.asList(items));
-    }
-
-    /**
-     * @deprecated use max(Iterable)
-     */
-    @Deprecated
-    public static <T> T max(Collection<T> items) {
-        return max((Iterable<T>)items);
-    }
-
-    /**
-     * Selects the maximum value found in an Iterable.
-     *
-     * @param items a Collection
-     * @return the maximum value
-     * @since 2.2.0
-     */
-    public static <T> T max(Iterable<T> items) {
-        T answer = null;
-        for (T value : items) {
-            if (value != null) {
-                if (answer == null || ScriptBytecodeAdapter.compareGreaterThan(value, answer)) {
-                    answer = value;
-                }
-            }
-        }
-        return answer;
-    }
-
-    /**
-     * Sums all the items from an array of items.
-     *
-     * @param items an array of items
-     * @return the sum of the items
-     */
-    public static Object sum(Object[] items) {
-        return sum((Iterable)Arrays.asList(items));
-    }
-
-    /**
-     * @deprecated use sum(Iterable)
-     */
-    @Deprecated
-    public static Object sum(Collection items) {
-        return sum((Iterable)items);
-    }
-
-    /**
-     * Sums all the given items.
-     *
-     * @param items an Iterable of items
-     * @return the sum of the item
-     * @since 2.2.0
-     */
-    public static Object sum(Iterable items) {
-        return DefaultGroovyMethods.sum(items);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/util/GroovyScriptEngine.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/util/GroovyScriptEngine.java b/src/main/groovy/util/GroovyScriptEngine.java
deleted file mode 100644
index 92e2486..0000000
--- a/src/main/groovy/util/GroovyScriptEngine.java
+++ /dev/null
@@ -1,694 +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 groovy.util;
-
-import groovy.lang.Binding;
-import groovy.lang.GroovyClassLoader;
-import groovy.lang.GroovyCodeSource;
-import groovy.lang.GroovyResourceLoader;
-import groovy.lang.Script;
-import org.codehaus.groovy.GroovyBugError;
-import org.codehaus.groovy.ast.ClassNode;
-import org.codehaus.groovy.ast.InnerClassNode;
-import org.codehaus.groovy.classgen.GeneratorContext;
-import org.codehaus.groovy.control.ClassNodeResolver;
-import org.codehaus.groovy.control.CompilationFailedException;
-import org.codehaus.groovy.control.CompilationUnit;
-import org.codehaus.groovy.control.CompilerConfiguration;
-import org.codehaus.groovy.control.Phases;
-import org.codehaus.groovy.control.SourceUnit;
-import org.codehaus.groovy.control.customizers.CompilationCustomizer;
-import org.codehaus.groovy.runtime.IOGroovyMethods;
-import org.codehaus.groovy.runtime.InvokerHelper;
-import org.codehaus.groovy.tools.gse.DependencyTracker;
-import org.codehaus.groovy.tools.gse.StringSetMap;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.lang.ref.WeakReference;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLConnection;
-import java.security.AccessController;
-import java.security.CodeSource;
-import java.security.PrivilegedAction;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * Specific script engine able to reload modified scripts as well as dealing properly
- * with dependent scripts.
- *
- * @author sam
- * @author Marc Palmer
- * @author Guillaume Laforge
- * @author Jochen Theodorou
- * @author Mattias Reichel
- */
-public class GroovyScriptEngine implements ResourceConnector {
-    private static final ClassLoader CL_STUB = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
-        public ClassLoader run() {
-            return new ClassLoader() {};
-        }
-    });
-
-    private static final URL[] EMPTY_URL_ARRAY = new URL[0];
-
-    private static class LocalData {
-        CompilationUnit cu;
-        final StringSetMap dependencyCache = new StringSetMap();
-        final Map<String, String> precompiledEntries = new HashMap<String, String>();
-    }
-
-    private static WeakReference<ThreadLocal<LocalData>> localData = new WeakReference<ThreadLocal<LocalData>>(null);
-
-    private static synchronized ThreadLocal<LocalData> getLocalData() {
-        ThreadLocal<LocalData> local = localData.get();
-        if (local != null) return local;
-        local = new ThreadLocal<LocalData>();
-        localData = new WeakReference<ThreadLocal<LocalData>>(local);
-        return local;
-    }
-
-    private final URL[] roots;
-    private final ResourceConnector rc;
-    private final ClassLoader parentLoader;
-    private GroovyClassLoader groovyLoader;
-    private final Map<String, ScriptCacheEntry> scriptCache = new ConcurrentHashMap<String, ScriptCacheEntry>();
-    private CompilerConfiguration config;
-
-    {
-        config = new CompilerConfiguration(CompilerConfiguration.DEFAULT);
-        config.setSourceEncoding(CompilerConfiguration.DEFAULT_SOURCE_ENCODING);
-    }
-
-
-    //TODO: more finals?
-
-    private static class ScriptCacheEntry {
-        private final Class scriptClass;
-        private final long lastModified, lastCheck;
-        private final Set<String> dependencies;
-        private final boolean sourceNewer;
-
-        public ScriptCacheEntry(Class clazz, long modified, long lastCheck, Set<String> depend, boolean sourceNewer) {
-            this.scriptClass = clazz;
-            this.lastModified = modified;
-            this.lastCheck = lastCheck;
-            this.dependencies = depend;
-            this.sourceNewer = sourceNewer;
-        }
-
-        public ScriptCacheEntry(ScriptCacheEntry old, long lastCheck, boolean sourceNewer) {
-            this(old.scriptClass, old.lastModified, lastCheck, old.dependencies, sourceNewer);
-        }
-    }
-
-    private class ScriptClassLoader extends GroovyClassLoader {
-
-
-        public ScriptClassLoader(GroovyClassLoader loader) {
-            super(loader);
-        }
-
-        public ScriptClassLoader(ClassLoader loader, CompilerConfiguration config) {
-            super(loader, config, false);
-            setResLoader();
-        }
-
-        private void setResLoader() {
-            final GroovyResourceLoader rl = getResourceLoader();
-            setResourceLoader(new GroovyResourceLoader() {
-                public URL loadGroovySource(String className) throws MalformedURLException {
-                    String filename;
-                    for (String extension : getConfig().getScriptExtensions()) {
-                        filename = className.replace('.', File.separatorChar) + "." + extension;
-                        try {
-                            URLConnection dependentScriptConn = rc.getResourceConnection(filename);
-                            return dependentScriptConn.getURL();
-                        } catch (ResourceException e) {
-                            //TODO: maybe do something here?
-                        }
-                    }
-                    return rl.loadGroovySource(className);
-                }
-            });
-        }
-
-        @Override
-        protected CompilationUnit createCompilationUnit(CompilerConfiguration configuration, CodeSource source) {
-            CompilationUnit cu = super.createCompilationUnit(configuration, source);
-            LocalData local = getLocalData().get();
-            local.cu = cu;
-            final StringSetMap cache = local.dependencyCache;
-            final Map<String, String> precompiledEntries = local.precompiledEntries;
-
-            // "." is used to transfer compilation dependencies, which will be
-            // recollected later during compilation
-            for (String depSourcePath : cache.get(".")) {
-                try {
-                    cache.get(depSourcePath);
-                    cu.addSource(getResourceConnection(depSourcePath).getURL());
-                } catch (ResourceException e) {
-                    /* ignore */
-                }
-            }
-
-            // remove all old entries including the "." entry
-            cache.clear();
-
-            cu.addPhaseOperation(new CompilationUnit.PrimaryClassNodeOperation() {
-                @Override
-                public void call(final SourceUnit source, GeneratorContext context, ClassNode classNode)
-                        throws CompilationFailedException {
-                    // GROOVY-4013: If it is an inner class, tracking its dependencies doesn't really
-                    // serve any purpose and also interferes with the caching done to track dependencies
-                    if (classNode instanceof InnerClassNode) return;
-                    DependencyTracker dt = new DependencyTracker(source, cache, precompiledEntries);
-                    dt.visitClass(classNode);
-                }
-            }, Phases.CLASS_GENERATION);
-
-            cu.setClassNodeResolver(new ClassNodeResolver() {
-                @Override
-                public LookupResult findClassNode(String origName, CompilationUnit compilationUnit) {
-                    CompilerConfiguration cc = compilationUnit.getConfiguration();
-                    String name = origName.replace('.', '/');
-                    for (String ext : cc.getScriptExtensions()) {
-                        try {
-                            String finalName = name + "." + ext;
-                            URLConnection conn = rc.getResourceConnection(finalName);
-                            URL url = conn.getURL();
-                            String path = url.toExternalForm();
-                            ScriptCacheEntry entry = scriptCache.get(path);
-                            Class clazz = null;
-                            if (entry != null) clazz = entry.scriptClass;
-                            if (GroovyScriptEngine.this.isSourceNewer(entry)) {
-                                try {
-                                    SourceUnit su = compilationUnit.addSource(url);
-                                    return new LookupResult(su, null);
-                                } finally {
-                                    forceClose(conn);
-                                }
-                            } else {
-                                precompiledEntries.put(origName, path);
-                            }
-                            if (clazz != null) {
-                                ClassNode cn = new ClassNode(clazz);
-                                return new LookupResult(null, cn);
-                            }
-                        } catch (ResourceException re) {
-                            // skip
-                        }
-                    }
-                    return super.findClassNode(origName, compilationUnit);
-                }
-            });
-
-            return cu;
-        }
-
-        @Override
-        public Class parseClass(GroovyCodeSource codeSource, boolean shouldCacheSource) throws CompilationFailedException {
-            synchronized (sourceCache) {
-                return doParseClass(codeSource);
-            }
-        }
-
-        private Class<?> doParseClass(GroovyCodeSource codeSource) {
-            // local is kept as hard reference to avoid garbage collection
-            ThreadLocal<LocalData> localTh = getLocalData();
-            LocalData localData = new LocalData();
-            localTh.set(localData);
-            StringSetMap cache = localData.dependencyCache;
-            Class<?> answer = null;
-            try {
-                updateLocalDependencyCache(codeSource, localData);
-                answer = super.parseClass(codeSource, false);
-                updateScriptCache(localData);
-            } finally {
-                cache.clear();
-                localTh.remove();
-            }
-            return answer;
-        }
-
-        private void updateLocalDependencyCache(GroovyCodeSource codeSource, LocalData localData) {
-            // we put the old dependencies into local cache so createCompilationUnit
-            // can pick it up. We put that entry under the name "."
-            ScriptCacheEntry origEntry = scriptCache.get(codeSource.getName());
-            Set<String> origDep = null;
-            if (origEntry != null) origDep = origEntry.dependencies;
-            if (origDep != null) {
-                Set<String> newDep = new HashSet<String>(origDep.size());
-                for (String depName : origDep) {
-                    ScriptCacheEntry dep = scriptCache.get(depName);
-                    try {
-                        if (origEntry == dep || GroovyScriptEngine.this.isSourceNewer(dep)) {
-                            newDep.add(depName);
-                        }
-                    } catch (ResourceException re) {
-
-                    }
-                }
-                StringSetMap cache = localData.dependencyCache;
-                cache.put(".", newDep);
-            }
-        }
-
-        private void updateScriptCache(LocalData localData) {
-            StringSetMap cache = localData.dependencyCache;
-            cache.makeTransitiveHull();
-            long time = getCurrentTime();
-            Set<String> entryNames = new HashSet<String>();
-            for (Map.Entry<String, Set<String>> entry : cache.entrySet()) {
-                String className = entry.getKey();
-                Class clazz = getClassCacheEntry(className);
-                if (clazz == null) continue;
-
-                String entryName = getPath(clazz, localData.precompiledEntries);
-                if (entryNames.contains(entryName)) continue;
-                entryNames.add(entryName);
-                Set<String> value = convertToPaths(entry.getValue(), localData.precompiledEntries);
-                long lastModified;
-                try {
-                    lastModified = getLastModified(entryName);
-                } catch (ResourceException e) {
-                    lastModified = time;
-                }
-                ScriptCacheEntry cacheEntry = new ScriptCacheEntry(clazz, lastModified, time, value, false);
-                scriptCache.put(entryName, cacheEntry);
-            }
-        }
-
-        private String getPath(Class clazz, Map<String, String> precompiledEntries) {
-            CompilationUnit cu = getLocalData().get().cu;
-            String name = clazz.getName();
-            ClassNode classNode = cu.getClassNode(name);
-            if (classNode == null) {
-                // this is a precompiled class!
-                String path = precompiledEntries.get(name);
-                if (path == null) throw new GroovyBugError("Precompiled class " + name + " should be available in precompiled entries map, but was not.");
-                return path;
-            } else {
-                return classNode.getModule().getContext().getName();
-            }
-        }
-
-        private Set<String> convertToPaths(Set<String> orig, Map<String, String> precompiledEntries) {
-            Set<String> ret = new HashSet<String>();
-            for (String className : orig) {
-                Class clazz = getClassCacheEntry(className);
-                if (clazz == null) continue;
-                ret.add(getPath(clazz, precompiledEntries));
-            }
-            return ret;
-        }
-    }
-
-    /**
-     * Simple testing harness for the GSE. Enter script roots as arguments and
-     * then input script names to run them.
-     *
-     * @param urls an array of URLs
-     * @throws Exception if something goes wrong
-     */
-    public static void main(String[] urls) throws Exception {
-        GroovyScriptEngine gse = new GroovyScriptEngine(urls);
-        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
-        String line;
-        while (true) {
-            System.out.print("groovy> ");
-            if ((line = br.readLine()) == null || line.equals("quit")) {
-                break;
-            }
-            try {
-                System.out.println(gse.run(line, new Binding()));
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-        }
-    }
-
-    /**
-     * Initialize a new GroovyClassLoader with a default or
-     * constructor-supplied parentClassLoader.
-     *
-     * @return the parent classloader used to load scripts
-     */
-    private GroovyClassLoader initGroovyLoader() {
-        GroovyClassLoader groovyClassLoader =
-                AccessController.doPrivileged(new PrivilegedAction<ScriptClassLoader>() {
-                    public ScriptClassLoader run() {
-                        if (parentLoader instanceof GroovyClassLoader) {
-                            return new ScriptClassLoader((GroovyClassLoader) parentLoader);
-                        } else {
-                            return new ScriptClassLoader(parentLoader, config);
-                        }
-                    }
-                });
-        for (URL root : roots) groovyClassLoader.addURL(root);
-        return groovyClassLoader;
-    }
-
-    /**
-     * Get a resource connection as a <code>URLConnection</code> to retrieve a script
-     * from the <code>ResourceConnector</code>.
-     *
-     * @param resourceName name of the resource to be retrieved
-     * @return a URLConnection to the resource
-     * @throws ResourceException
-     */
-    public URLConnection getResourceConnection(String resourceName) throws ResourceException {
-        // Get the URLConnection
-        URLConnection groovyScriptConn = null;
-
-        ResourceException se = null;
-        for (URL root : roots) {
-            URL scriptURL = null;
-            try {
-                scriptURL = new URL(root, resourceName);
-                groovyScriptConn = openConnection(scriptURL);
-
-                break; // Now this is a bit unusual
-            } catch (MalformedURLException e) {
-                String message = "Malformed URL: " + root + ", " + resourceName;
-                if (se == null) {
-                    se = new ResourceException(message);
-                } else {
-                    se = new ResourceException(message, se);
-                }
-            } catch (IOException e1) {
-                String message = "Cannot open URL: " + root + resourceName;
-                groovyScriptConn = null;
-                if (se == null) {
-                    se = new ResourceException(message);
-                } else {
-                    se = new ResourceException(message, se);
-                }
-            }
-        }
-
-        if (se == null) se = new ResourceException("No resource for " + resourceName + " was found");
-
-        // If we didn't find anything, report on all the exceptions that occurred.
-        if (groovyScriptConn == null) throw se;
-        return groovyScriptConn;
-    }
-
-    private static URLConnection openConnection(URL scriptURL) throws IOException {
-        URLConnection urlConnection = scriptURL.openConnection();
-        verifyInputStream(urlConnection);
-
-        return scriptURL.openConnection();
-    }
-
-    /**
-     * This method closes a {@link URLConnection} by getting its {@link InputStream} and calling the
-     * {@link InputStream#close()} method on it. The {@link URLConnection} doesn't have a close() method
-     * and relies on garbage collection to close the underlying connection to the file.
-     * Relying on garbage collection could lead to the application exhausting the number of files the
-     * user is allowed to have open at any one point in time and cause the application to crash
-     * ({@link java.io.FileNotFoundException} (Too many open files)).
-     * Hence the need for this method to explicitly close the underlying connection to the file.
-     *
-     * @param urlConnection the {@link URLConnection} to be "closed" to close the underlying file descriptors.
-     */
-    private static void forceClose(URLConnection urlConnection) {
-        if (urlConnection != null) {
-            // We need to get the input stream and close it to force the open
-            // file descriptor to be released. Otherwise, we will reach the limit
-            // for number of files open at one time.
-
-            try {
-                verifyInputStream(urlConnection);
-            } catch (Exception e) {
-                // Do nothing: We were not going to use it anyway.
-            }
-        }
-    }
-
-    private static void verifyInputStream(URLConnection urlConnection) throws IOException {
-        InputStream in = null;
-        try {
-            in = urlConnection.getInputStream();
-        } finally {
-            if (in != null) {
-                try {
-                    in.close();
-                } catch (IOException ignore) {
-                }
-            }
-        }
-    }
-
-    /**
-     * The groovy script engine will run groovy scripts and reload them and
-     * their dependencies when they are modified. This is useful for embedding
-     * groovy in other containers like games and application servers.
-     *
-     * @param roots This an array of URLs where Groovy scripts will be stored. They should
-     *              be laid out using their package structure like Java classes
-     */
-    private GroovyScriptEngine(URL[] roots, ClassLoader parent, ResourceConnector rc) {
-        if (roots == null) roots = EMPTY_URL_ARRAY;
-        this.roots = roots;
-        if (rc == null) rc = this;
-        this.rc = rc;
-        if (parent == CL_STUB) parent = this.getClass().getClassLoader();
-        this.parentLoader = parent;
-        this.groovyLoader = initGroovyLoader();
-    }
-
-    public GroovyScriptEngine(URL[] roots) {
-        this(roots, CL_STUB, null);
-    }
-
-    public GroovyScriptEngine(URL[] roots, ClassLoader parentClassLoader) {
-        this(roots, parentClassLoader, null);
-    }
-
-    public GroovyScriptEngine(String[] urls) throws IOException {
-        this(createRoots(urls), CL_STUB, null);
-    }
-
-    private static URL[] createRoots(String[] urls) throws MalformedURLException {
-        if (urls == null) return null;
-        URL[] roots = new URL[urls.length];
-        for (int i = 0; i < roots.length; i++) {
-            if (urls[i].contains("://")) {
-                roots[i] = new URL(urls[i]);
-            } else {
-                roots[i] = new File(urls[i]).toURI().toURL();
-            }
-        }
-        return roots;
-    }
-
-    public GroovyScriptEngine(String[] urls, ClassLoader parentClassLoader) throws IOException {
-        this(createRoots(urls), parentClassLoader, null);
-    }
-
-    public GroovyScriptEngine(String url) throws IOException {
-        this(new String[]{url});
-    }
-
-    public GroovyScriptEngine(String url, ClassLoader parentClassLoader) throws IOException {
-        this(new String[]{url}, parentClassLoader);
-    }
-
-    public GroovyScriptEngine(ResourceConnector rc) {
-        this(null, CL_STUB, rc);
-    }
-
-    public GroovyScriptEngine(ResourceConnector rc, ClassLoader parentClassLoader) {
-        this(null, parentClassLoader, rc);
-    }
-
-    /**
-     * Get the <code>ClassLoader</code> that will serve as the parent ClassLoader of the
-     * {@link GroovyClassLoader} in which scripts will be executed. By default, this is the
-     * ClassLoader that loaded the <code>GroovyScriptEngine</code> class.
-     *
-     * @return the parent classloader used to load scripts
-     */
-    public ClassLoader getParentClassLoader() {
-        return parentLoader;
-    }
-
-    /**
-     * Get the class of the scriptName in question, so that you can instantiate
-     * Groovy objects with caching and reloading.
-     *
-     * @param scriptName resource name pointing to the script
-     * @return the loaded scriptName as a compiled class
-     * @throws ResourceException if there is a problem accessing the script
-     * @throws ScriptException   if there is a problem parsing the script
-     */
-    public Class loadScriptByName(String scriptName) throws ResourceException, ScriptException {
-        URLConnection conn = rc.getResourceConnection(scriptName);
-        String path = conn.getURL().toExternalForm();
-        ScriptCacheEntry entry = scriptCache.get(path);
-        Class clazz = null;
-        if (entry != null) clazz = entry.scriptClass;
-        try {
-            if (isSourceNewer(entry)) {
-                try {
-                    String encoding = conn.getContentEncoding() != null ? conn.getContentEncoding() : config.getSourceEncoding();
-                    String content = IOGroovyMethods.getText(conn.getInputStream(), encoding);
-                    clazz = groovyLoader.parseClass(content, path);
-                } catch (IOException e) {
-                    throw new ResourceException(e);
-                }
-            }
-        } finally {
-            forceClose(conn);
-        }
-        return clazz;
-    }
-
-    /**
-     * Run a script identified by name with a single argument.
-     *
-     * @param scriptName name of the script to run
-     * @param argument   a single argument passed as a variable named <code>arg</code> in the binding
-     * @return a <code>toString()</code> representation of the result of the execution of the script
-     * @throws ResourceException if there is a problem accessing the script
-     * @throws ScriptException   if there is a problem parsing the script
-     */
-    public String run(String scriptName, String argument) throws ResourceException, ScriptException {
-        Binding binding = new Binding();
-        binding.setVariable("arg", argument);
-        Object result = run(scriptName, binding);
-        return result == null ? "" : result.toString();
-    }
-
-    /**
-     * Run a script identified by name with a given binding.
-     *
-     * @param scriptName name of the script to run
-     * @param binding    the binding to pass to the script
-     * @return an object
-     * @throws ResourceException if there is a problem accessing the script
-     * @throws ScriptException   if there is a problem parsing the script
-     */
-    public Object run(String scriptName, Binding binding) throws ResourceException, ScriptException {
-        return createScript(scriptName, binding).run();
-    }
-
-    /**
-     * Creates a Script with a given scriptName and binding.
-     *
-     * @param scriptName name of the script to run
-     * @param binding    the binding to pass to the script
-     * @return the script object
-     * @throws ResourceException if there is a problem accessing the script
-     * @throws ScriptException   if there is a problem parsing the script
-     */
-    public Script createScript(String scriptName, Binding binding) throws ResourceException, ScriptException {
-        return InvokerHelper.createScript(loadScriptByName(scriptName), binding);
-    }
-
-    private long getLastModified(String scriptName) throws ResourceException {
-        URLConnection conn = rc.getResourceConnection(scriptName);
-        long lastMod = 0;
-        try {
-            lastMod = conn.getLastModified();
-        } finally {
-            // getResourceConnection() opening the inputstream, let's ensure all streams are closed
-            forceClose(conn);
-        }
-        return lastMod;
-    }
-
-    protected boolean isSourceNewer(ScriptCacheEntry entry) throws ResourceException {
-        if (entry == null) return true;
-
-        long mainEntryLastCheck = entry.lastCheck;
-        long now = 0;
-
-        boolean returnValue = false;
-        for (String scriptName : entry.dependencies) {
-            ScriptCacheEntry depEntry = scriptCache.get(scriptName);
-            if (depEntry.sourceNewer) return true;
-
-            // check if maybe dependency was recompiled, but this one here not
-            if (mainEntryLastCheck < depEntry.lastModified) {
-                returnValue = true;
-                continue;
-            }
-
-            if (now == 0) now = getCurrentTime();
-            long nextSourceCheck = depEntry.lastCheck + config.getMinimumRecompilationInterval();
-            if (nextSourceCheck > now) continue;
-
-            long lastMod = getLastModified(scriptName);
-            if (depEntry.lastModified < lastMod) {
-                depEntry = new ScriptCacheEntry(depEntry, lastMod, true);
-                scriptCache.put(scriptName, depEntry);
-                returnValue = true;
-            } else {
-                depEntry = new ScriptCacheEntry(depEntry, now, false);
-                scriptCache.put(scriptName, depEntry);
-            }
-        }
-
-        return returnValue;
-    }
-
-    /**
-     * Returns the GroovyClassLoader associated with this script engine instance.
-     * Useful if you need to pass the class loader to another library.
-     *
-     * @return the GroovyClassLoader
-     */
-    public GroovyClassLoader getGroovyClassLoader() {
-        return groovyLoader;
-    }
-
-    /**
-     * @return a non null compiler configuration
-     */
-    public CompilerConfiguration getConfig() {
-        return config;
-    }
-
-    /**
-     * sets a compiler configuration
-     *
-     * @param config - the compiler configuration
-     * @throws NullPointerException if config is null
-     */
-    public void setConfig(CompilerConfiguration config) {
-        if (config == null) throw new NullPointerException("configuration cannot be null");
-        this.config = config;
-        this.groovyLoader = initGroovyLoader();
-    }
-
-    protected long getCurrentTime() {
-        return System.currentTimeMillis();
-    }
-}

http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/util/IFileNameFinder.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/util/IFileNameFinder.java b/src/main/groovy/util/IFileNameFinder.java
deleted file mode 100644
index 35e9012..0000000
--- a/src/main/groovy/util/IFileNameFinder.java
+++ /dev/null
@@ -1,26 +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 groovy.util;
-
-import java.util.List;
-
-public interface IFileNameFinder {
-    List<String> getFileNames(String basedir, String pattern);
-    List<String> getFileNames(String basedir, String pattern, String excludesPattern);
-}

http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/util/IndentPrinter.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/util/IndentPrinter.java b/src/main/groovy/util/IndentPrinter.java
deleted file mode 100644
index df3d8c2..0000000
--- a/src/main/groovy/util/IndentPrinter.java
+++ /dev/null
@@ -1,234 +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 groovy.util;
-
-import groovy.lang.GroovyRuntimeException;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.Writer;
-
-/**
- * A helper class for printing indented text. This can be used stand-alone or, more commonly, from Builders.
- * <p>
- * By default, a PrintWriter to System.out is used as the Writer, but it is possible
- * to change the Writer by passing a new one as a constructor argument.
- * <p>
- * Indention by default is 2 characters but can be changed by passing a
- * different value as a constructor argument.
- * <p>
- * The following is an example usage. Note that within a "with" block you need to
- * specify a parameter name so that this.println is not called instead of IndentPrinter.println:
- * <pre>
- * new IndentPrinter(new PrintWriter(out)).with { p ->
- *     p.printIndent()
- *     p.println('parent1')
- *     p.incrementIndent()
- *     p.printIndent()
- *     p.println('child 1')
- *     p.printIndent()
- *     p.println('child 2')
- *     p.decrementIndent()
- *     p.printIndent()
- *     p.println('parent2')
- *     p.flush()
- * }
- * </pre>
- * The above example prints this to standard output:
- * <pre>
- * parent1
- *   child 1
- *   child 2
- * parent2
- * </pre>
- *
- * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
- */
-public class IndentPrinter {
-
-    private int indentLevel;
-    private final String indent;
-    private final Writer out;
-    private final boolean addNewlines;
-    private boolean autoIndent;
-
-    /**
-     * Creates an IndentPrinter backed by a PrintWriter pointing to System.out, with an indent of two spaces.
-     *
-     * @see #IndentPrinter(Writer, String)
-     */
-    public IndentPrinter() {
-        this(new PrintWriter(System.out), "  ");
-    }
-
-    /**
-     * Creates an IndentPrinter backed by the supplied Writer, with an indent of two spaces.
-     *
-     * @param out Writer to output to
-     * @see #IndentPrinter(Writer, String)
-     */
-    public IndentPrinter(Writer out) {
-        this(out, "  ");
-    }
-
-    /**
-     * Creates an IndentPrinter backed by the supplied Writer,
-     * with a user-supplied String to be used for indenting.
-     *
-     * @param out Writer to output to
-     * @param indent character(s) used to indent each line
-     */
-    public IndentPrinter(Writer out, String indent) {
-        this(out, indent, true);
-    }
-
-    /**
-     * Creates an IndentPrinter backed by the supplied Writer,
-     * with a user-supplied String to be used for indenting
-     * and the ability to override newline handling.
-     *
-     * @param out Writer to output to
-     * @param indent character(s) used to indent each line
-     * @param addNewlines set to false to gobble all new lines (default true)
-     */
-    public IndentPrinter(Writer out, String indent, boolean addNewlines) {
-       this(out, indent, addNewlines, false);
-    }
-
-    /**
-     * Create an IndentPrinter to the given PrintWriter
-     * @param out Writer to output to
-     * @param indent character(s) used to indent each line
-     * @param addNewlines set to false to gobble all new lines (default true)
-     * @param autoIndent set to true to make println() prepend the indent automatically (default false)
-     */
-    public IndentPrinter(Writer out, String indent, boolean addNewlines, boolean autoIndent) {
-        this.addNewlines = addNewlines;
-        if (out == null) {
-            throw new IllegalArgumentException("Must specify a Writer");
-        }
-        this.out = out;
-        this.indent = indent;
-        this.autoIndent = autoIndent;
-    }
-
-    /**
-     * Prints a string followed by an end of line character.
-     *
-     * @param  text String to be written
-     */
-    public void println(String text) {
-        try {
-            if(autoIndent) printIndent();
-            out.write(text);
-            println();
-        } catch(IOException ioe) {
-            throw new GroovyRuntimeException(ioe);
-        }
-    }
-
-    /**
-     * Prints a string.
-     *
-     * @param  text String to be written
-     */
-    public void print(String text) {
-        try {
-            out.write(text);
-        } catch(IOException ioe) {
-            throw new GroovyRuntimeException(ioe);
-        }
-    }
-
-    /**
-     * Prints a character.
-     *
-     * @param  c char to be written
-     */
-    public void print(char c) {
-        try {
-            out.write(c);
-        } catch(IOException ioe) {
-            throw new GroovyRuntimeException(ioe);
-        }
-    }
-
-    /**
-     * Prints the current indent level.
-     */
-    public void printIndent() {
-        for (int i = 0; i < indentLevel; i++) {
-            try {
-                out.write(indent);
-            } catch(IOException ioe) {
-                throw new GroovyRuntimeException(ioe);
-            }
-        }
-    }
-
-    /**
-     * Prints an end-of-line character (if enabled via addNewLines property).
-     * Defaults to outputting a single '\n' character but by using a custom
-     * Writer, e.g. PlatformLineWriter, you can get platform-specific
-     * end-of-line characters.
-     *
-     * @see #IndentPrinter(Writer, String, boolean)
-     */
-    public void println() {
-        if (addNewlines) {
-            try {
-                out.write("\n");
-            } catch(IOException ioe) {
-                throw new GroovyRuntimeException(ioe);
-            }
-        }
-    }
-
-    public void incrementIndent() {
-        ++indentLevel;
-    }
-
-    public void decrementIndent() {
-        --indentLevel;
-    }
-
-    public int getIndentLevel() {
-        return indentLevel;
-    }
-
-    public void setIndentLevel(int indentLevel) {
-        this.indentLevel = indentLevel;
-    }
-
-    public boolean getAutoIndent(){
-        return this.autoIndent;
-    }
-
-    public void setAutoIndent(boolean autoIndent){
-        this.autoIndent = autoIndent;
-    }
-
-    public void flush() {
-        try {
-            out.flush();
-        } catch(IOException ioe) {
-            throw new GroovyRuntimeException(ioe);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/util/MapEntry.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/util/MapEntry.java b/src/main/groovy/util/MapEntry.java
deleted file mode 100644
index 9190fcd..0000000
--- a/src/main/groovy/util/MapEntry.java
+++ /dev/null
@@ -1,83 +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 groovy.util;
-
-import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation;
-
-import java.util.Map;
-
-/**
- * A Map.Entry implementation.
- * 
- * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
- */
-public class MapEntry implements Map.Entry {
-
-    private Object key;
-    private Object value;
-
-    public MapEntry(Object key, Object value) {
-        this.key = key;
-        this.value = value;
-    }
-
-    public boolean equals(Object that) {
-        if (that instanceof MapEntry) {
-            return equals((MapEntry) that);
-        }
-        return false;
-    }
-
-    public boolean equals(MapEntry that) {
-        return DefaultTypeTransformation.compareEqual(this.key, that.key) && DefaultTypeTransformation.compareEqual(this.value, that.value);
-    }
-
-    public int hashCode() {
-        return hash(key) ^ hash(value);
-    }
-
-    public String toString() {
-        return "" + key + ":" + value;
-    }
-
-    public Object getKey() {
-        return key;
-    }
-
-    public void setKey(Object key) {
-        this.key = key;
-    }
-
-    public Object getValue() {
-        return value;
-    }
-
-    public Object setValue(Object value) {
-        this.value = value;
-        return value;
-    }
-
-    /**
-     * Helper method to handle object hashes for possibly null values
-     */
-    protected int hash(Object object) {
-        return (object == null) ? 0xbabe : object.hashCode();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/util/Node.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/util/Node.java b/src/main/groovy/util/Node.java
deleted file mode 100644
index e40b14a..0000000
--- a/src/main/groovy/util/Node.java
+++ /dev/null
@@ -1,787 +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 groovy.util;
-
-import groovy.lang.Closure;
-import groovy.lang.DelegatingMetaClass;
-import groovy.lang.GroovySystem;
-import groovy.lang.MetaClass;
-import groovy.lang.Tuple2;
-import groovy.xml.QName;
-import org.codehaus.groovy.runtime.DefaultGroovyMethods;
-import org.codehaus.groovy.runtime.InvokerHelper;
-import org.codehaus.groovy.util.ListHashMap;
-
-import java.io.PrintWriter;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Stack;
-
-/**
- * Represents an arbitrary tree node which can be used for structured metadata or any arbitrary XML-like tree.
- * A node can have a name, a value and an optional Map of attributes.
- * Typically the name is a String and a value is either a String or a List of other Nodes,
- * though the types are extensible to provide a flexible structure, e.g. you could use a
- * QName as the name which includes a namespace URI and a local name. Or a JMX ObjectName etc.
- * So this class can represent metadata like <code>{foo a=1 b="abc"}</code> or nested
- * metadata like <code>{foo a=1 b="123" { bar x=12 text="hello" }}</code>
- *
- * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
- * @author Paul King
- */
-public class Node implements Serializable, Cloneable {
-
-    static {
-        // wrap the standard MetaClass with the delegate
-        setMetaClass(GroovySystem.getMetaClassRegistry().getMetaClass(Node.class), Node.class);
-    }
-
-    private static final long serialVersionUID = 4121134753270542643L;
-
-    private Node parent;
-
-    private final Object name;
-
-    private final Map attributes;
-
-    private Object value;
-
-    /**
-     * Creates a new Node with the same name, no parent, shallow cloned attributes
-     * and if the value is a NodeList, a (deep) clone of those nodes.
-     *
-     * @return the clone
-     */
-    @Override
-    public Object clone() {
-        Object newValue = value;
-        if (value != null && value instanceof NodeList) {
-            NodeList nodes = (NodeList) value;
-            newValue = nodes.clone();
-        }
-        return new Node(null, name, new HashMap(attributes), newValue);
-    }
-
-    /**
-     * Creates a new Node named <code>name</code> and if a parent is supplied, adds
-     * the newly created node as a child of the parent.
-     *
-     * @param parent the parent node or null if no parent
-     * @param name   the name of the node
-     */
-    public Node(Node parent, Object name) {
-        this(parent, name, new NodeList());
-    }
-
-    /**
-     * Creates a new Node named <code>name</code> with value <code>value</code> and
-     * if a parent is supplied, adds the newly created node as a child of the parent.
-     *
-     * @param parent the parent node or null if no parent
-     * @param name   the name of the node
-     * @param value  the Node value, e.g. some text but in general any Object
-     */
-    public Node(Node parent, Object name, Object value) {
-        this(parent, name, new HashMap(), value);
-    }
-
-    /**
-     * Creates a new Node named <code>name</code> with
-     * attributes specified in the <code>attributes</code> Map. If a parent is supplied,
-     * the newly created node is added as a child of the parent.
-     *
-     * @param parent     the parent node or null if no parent
-     * @param name       the name of the node
-     * @param attributes a Map of name-value pairs
-     */
-    public Node(Node parent, Object name, Map attributes) {
-        this(parent, name, attributes, new NodeList());
-    }
-
-    /**
-     * Creates a new Node named <code>name</code> with value <code>value</code> and
-     * with attributes specified in the <code>attributes</code> Map. If a parent is supplied,
-     * the newly created node is added as a child of the parent.
-     *
-     * @param parent     the parent node or null if no parent
-     * @param name       the name of the node
-     * @param attributes a Map of name-value pairs
-     * @param value      the Node value, e.g. some text but in general any Object
-     */
-    public Node(Node parent, Object name, Map attributes, Object value) {
-        this.parent = parent;
-        this.name = name;
-        this.attributes = attributes;
-        this.value = value;
-
-        if (parent != null) {
-            getParentList(parent).add(this);
-        }
-    }
-
-    private static List getParentList(Node parent) {
-        Object parentValue = parent.value();
-        List parentList;
-        if (parentValue instanceof List) {
-            parentList = (List) parentValue;
-        } else {
-            parentList = new NodeList();
-            parentList.add(parentValue);
-            parent.setValue(parentList);
-        }
-        return parentList;
-    }
-
-    /**
-     * Appends a child to the current node.
-     *
-     * @param child the child to append
-     * @return <code>true</code>
-     */
-    public boolean append(Node child) {
-        child.setParent(this);
-        return getParentList(this).add(child);
-    }
-
-    /**
-     * Removes a child of the current node.
-     *
-     * @param child the child to remove
-     * @return <code>true</code> if the param was a child of the current node
-     */
-    public boolean remove(Node child) {
-        child.setParent(null);
-        return getParentList(this).remove(child);
-    }
-
-    /**
-     * Creates a new node as a child of the current node.
-     *
-     * @param name the name of the new node
-     * @param attributes the attributes of the new node
-     * @return the newly created <code>Node</code>
-     */
-    public Node appendNode(Object name, Map attributes) {
-        return new Node(this, name, attributes);
-    }
-
-    /**
-     * Creates a new node as a child of the current node.
-     *
-     * @param name the name of the new node
-     * @return the newly created <code>Node</code>
-     */
-    public Node appendNode(Object name) {
-        return new Node(this, name);
-    }
-
-    /**
-     * Creates a new node as a child of the current node.
-     *
-     * @param name the name of the new node
-     * @param value the value of the new node
-     * @return the newly created <code>Node</code>
-     */
-    public Node appendNode(Object name, Object value) {
-        return new Node(this, name, value);
-    }
-
-    /**
-     * Creates a new node as a child of the current node.
-     *
-     * @param name the name of the new node
-     * @param attributes the attributes of the new node
-     * @param value the value of the new node
-     * @return the newly created <code>Node</code>
-     */
-    public Node appendNode(Object name, Map attributes, Object value) {
-        return new Node(this, name, attributes, value);
-    }
-
-    /**
-     * Replaces the current node with nodes defined using builder-style notation via a Closure.
-     *
-     * @param c A Closure defining the new nodes using builder-style notation.
-     * @return the original now replaced node
-     */
-    public Node replaceNode(Closure c) {
-        if (parent() == null) {
-            throw new UnsupportedOperationException("Replacing the root node is not supported");
-        }
-        appendNodes(c);
-        getParentList(parent()).remove(this);
-        this.setParent(null);
-        return this;
-    }
-
-    /**
-     * Replaces the current node with the supplied node.
-     *
-     * @param n the new Node
-     * @return the original now replaced node
-     */
-    public Node replaceNode(Node n) {
-        if (parent() == null) {
-            throw new UnsupportedOperationException("Replacing the root node is not supported");
-        }
-        List tail = getTail();
-        parent().appendNode(n.name(), n.attributes(), n.value());
-        parent().children().addAll(tail);
-        getParentList(parent()).remove(this);
-        this.setParent(null);
-        return this;
-    }
-
-    private List getTail() {
-        List list = parent().children();
-        int afterIndex = list.indexOf(this);
-        List tail = new ArrayList(list.subList(afterIndex + 1, list.size()));
-        list.subList(afterIndex + 1, list.size()).clear();
-        return tail;
-    }
-
-    /**
-     * Adds sibling nodes (defined using builder-style notation via a Closure) after the current node.
-     *
-     * @param c A Closure defining the new sibling nodes to add using builder-style notation.
-     */
-    public void plus(Closure c) {
-        if (parent() == null) {
-            throw new UnsupportedOperationException("Adding sibling nodes to the root node is not supported");
-        }
-        appendNodes(c);
-    }
-
-    private void appendNodes(Closure c) {
-        List tail = getTail();
-        for (Node child : buildChildrenFromClosure(c)) {
-            parent().appendNode(child.name(), child.attributes(), child.value());
-        }
-        parent().children().addAll(tail);
-    }
-
-    private static List<Node> buildChildrenFromClosure(Closure c) {
-        NodeBuilder b = new NodeBuilder();
-        Node newNode = (Node) b.invokeMethod("dummyNode", c);
-        return newNode.children();
-    }
-
-    /**
-     * Extension point for subclasses to override the metaclass. The default
-     * one supports the property and @ attribute notations.
-     *
-     * @param metaClass the original metaclass
-     * @param nodeClass the class whose metaclass we wish to override (this class or a subclass)
-     */
-    protected static void setMetaClass(final MetaClass metaClass, Class nodeClass) {
-        // TODO Is protected static a bit of a smell?
-        // TODO perhaps set nodeClass to be Class<? extends Node>
-        final MetaClass newMetaClass = new DelegatingMetaClass(metaClass) {
-            @Override
-            public Object getAttribute(final Object object, final String attribute) {
-                Node n = (Node) object;
-                return n.get("@" + attribute);
-            }
-
-            @Override
-            public void setAttribute(final Object object, final String attribute, final Object newValue) {
-                Node n = (Node) object;
-                n.attributes().put(attribute, newValue);
-            }
-
-            @Override
-            public Object getProperty(Object object, String property) {
-                if (object instanceof Node) {
-                    Node n = (Node) object;
-                    return n.get(property);
-                }
-                return super.getProperty(object, property);
-            }
-
-            @Override
-            public void setProperty(Object object, String property, Object newValue) {
-                if (property.startsWith("@")) {
-                    setAttribute(object, property.substring(1), newValue);
-                    return;
-                }
-                delegate.setProperty(object, property, newValue);
-            }
-
-        };
-        GroovySystem.getMetaClassRegistry().setMetaClass(nodeClass, newMetaClass);
-    }
-
-    /**
-     * Returns the textual representation of the current node and all its child nodes.
-     *
-     * @return the text value of the node including child text
-     */
-    public String text() {
-        if (value instanceof String) {
-            return (String) value;
-        }
-        if (value instanceof NodeList) {
-            return ((NodeList) value).text();
-        }
-        if (value instanceof Collection) {
-            Collection coll = (Collection) value;
-            String previousText = null;
-            StringBuilder sb = null;
-            for (Object child : coll) {
-                String childText = null;
-                if (child instanceof String) {
-                    childText = (String) child;
-                } else if (child instanceof Node) {
-                    childText = ((Node) child).text();
-                }
-                if (childText != null) {
-                    if (previousText == null) {
-                        previousText = childText;
-                    } else {
-                        if (sb == null) {
-                            sb = new StringBuilder();
-                            sb.append(previousText);
-                        }
-                        sb.append(childText);
-                    }
-                }
-            }
-            if (sb != null) {
-                return sb.toString();
-            } else {
-                if (previousText != null) {
-                    return previousText;
-                }
-                return "";
-            }
-        }
-        return "" + value;
-    }
-
-    /**
-     * Returns an <code>Iterator</code> of the children of the node.
-     *
-     * @return the iterator of the nodes children
-     */
-    public Iterator iterator() {
-        return children().iterator();
-    }
-
-    /**
-     * Returns a <code>List</code> of the nodes children.
-     *
-     * @return the nodes children
-     */
-    public List children() {
-        if (value == null) {
-            return new NodeList();
-        }
-        if (value instanceof List) {
-            return (List) value;
-        }
-        // we're probably just a String
-        List result = new NodeList();
-        result.add(value);
-        return result;
-    }
-
-    /**
-     * Returns a <code>Map</code> of the attributes of the node or an empty <code>Map</code>
-     * if the node does not have any attributes.
-     *
-     * @return the attributes of the node
-     */
-    public Map attributes() {
-        return attributes;
-    }
-
-    /**
-     * Provides lookup of attributes by key.
-     *
-     * @param key the key of interest
-     * @return the attribute matching the key or <code>null</code> if no match exists
-     */
-    public Object attribute(Object key) {
-        return (attributes != null) ? attributes.get(key) : null;
-    }
-
-    /**
-     * Returns an <code>Object</code> representing the name of the node.
-     *
-     * @return the name or <code>null</code> if name is empty
-     */
-    public Object name() {
-        return name;
-    }
-
-    /**
-     * Returns an <code>Object</code> representing the value of the node.
-     *
-     * @return the value or <code>null</code> if value is empty
-     */
-    public Object value() {
-        return value;
-    }
-
-    /**
-     * Adds or replaces the value of the node.
-     *
-     * @param value the new value of the node
-     */
-    public void setValue(Object value) {
-        this.value = value;
-    }
-
-    /**
-     * Returns the parent of the node.
-     *
-     * @return the parent or <code>null</code> for the root node
-     */
-    public Node parent() {
-        return parent;
-    }
-
-    /**
-     * Adds or replaces the parent of the node.
-     *
-     * @param parent the new parent of the node
-     */
-    protected void setParent(Node parent) {
-        this.parent = parent;
-    }
-
-    /**
-     * Provides lookup of elements by non-namespaced name
-     *
-     * @param key the name (or shortcut key) of the node(s) of interest
-     * @return the nodes which match key
-     */
-    public Object get(String key) {
-        if (key != null && key.charAt(0) == '@') {
-            String attributeName = key.substring(1);
-            return attributes().get(attributeName);
-        }
-        if ("..".equals(key)) {
-            return parent();
-        }
-        if ("*".equals(key)) {
-            return children();
-        }
-        if ("**".equals(key)) {
-            return depthFirst();
-        }
-        return getByName(key);
-    }
-
-    /**
-     * Provides lookup of elements by QName.
-     *
-     * @param name the QName of interest
-     * @return the nodes matching name
-     */
-    public NodeList getAt(QName name) {
-        NodeList answer = new NodeList();
-        for (Object child : children()) {
-            if (child instanceof Node) {
-                Node childNode = (Node) child;
-                Object childNodeName = childNode.name();
-                if (name.matches(childNodeName)) {
-                    answer.add(childNode);
-                }
-            }
-        }
-        return answer;
-    }
-
-    /**
-     * Provides lookup of elements by name.
-     *
-     * @param name the name of interest
-     * @return the nodes matching name
-     */
-    private NodeList getByName(String name) {
-        NodeList answer = new NodeList();
-        for (Object child : children()) {
-            if (child instanceof Node) {
-                Node childNode = (Node) child;
-                Object childNodeName = childNode.name();
-                if (childNodeName instanceof QName) {
-                    QName qn = (QName) childNodeName;
-                    if (qn.matches(name)) {
-                        answer.add(childNode);
-                    }
-                } else if (name.equals(childNodeName)) {
-                    answer.add(childNode);
-                }
-            }
-        }
-        return answer;
-    }
-
-    /**
-     * Provides a collection of all the nodes in the tree
-     * using a depth-first preorder traversal.
-     *
-     * @return the list of (depth-first) ordered nodes
-     */
-    public List depthFirst() {
-        return depthFirst(true);
-    }
-
-    /**
-     * Provides a collection of all the nodes in the tree
-     * using a depth-first traversal.
-     *
-     * @param preorder if false, a postorder depth-first traversal will be performed
-     * @return the list of (depth-first) ordered nodes
-     * @since 2.5.0
-     */
-    public List depthFirst(boolean preorder) {
-        List answer = new NodeList();
-        if (preorder) answer.add(this);
-        answer.addAll(depthFirstRest(preorder));
-        if (!preorder) answer.add(this);
-        return answer;
-    }
-
-    private List depthFirstRest(boolean preorder) {
-        List answer = new NodeList();
-        for (Iterator iter = InvokerHelper.asIterator(value); iter.hasNext(); ) {
-            Object child = iter.next();
-            if (child instanceof Node) {
-                Node childNode = (Node) child;
-                List children = childNode.depthFirstRest(preorder);
-                if (preorder) answer.add(childNode);
-                if (children.size() > 1 || (children.size() == 1 && !(children.get(0) instanceof String))) answer.addAll(children);
-                if (!preorder) answer.add(childNode);
-            } else if (child instanceof String) {
-                answer.add(child);
-            }
-        }
-        return answer;
-    }
-
-    /**
-     * Provides a collection of all the nodes in the tree
-     * using a depth-first preorder traversal.
-     *
-     * @param c the closure to run for each node (a one or two parameter can be used; if one parameter is given the
-     *          closure will be passed the node, for a two param closure the second parameter will be the level).
-     * @since 2.5.0
-     */
-    public void depthFirst(Closure c) {
-        Map<String, Object> options = new ListHashMap<String, Object>();
-        options.put("preorder", true);
-        depthFirst(options, c);
-    }
-
-    /**
-     * Provides a collection of all the nodes in the tree
-     * using a depth-first traversal.
-     * A boolean 'preorder' options is supported.
-     *
-     * @param options map containing options
-     * @param c the closure to run for each node (a one or two parameter can be used; if one parameter is given the
-     *          closure will be passed the node, for a two param closure the second parameter will be the level).
-     * @since 2.5.0
-     */
-    public void depthFirst(Map<String, Object> options, Closure c) {
-        boolean preorder = Boolean.valueOf(options.get("preorder").toString());
-        if (preorder) callClosureForNode(c, this, 1);
-        depthFirstRest(preorder, 2, c);
-        if (!preorder) callClosureForNode(c, this, 1);
-    }
-
-    private static <T> T callClosureForNode(Closure<T> closure, Object node, int level) {
-        if (closure.getMaximumNumberOfParameters() == 2) {
-            return closure.call(new Object[]{node, level});
-        }
-        return closure.call(node);
-    }
-
-    private void depthFirstRest(boolean preorder, int level, Closure c) {
-        for (Iterator iter = InvokerHelper.asIterator(value); iter.hasNext(); ) {
-            Object child = iter.next();
-            if (child instanceof Node) {
-                Node childNode = (Node) child;
-                if (preorder) callClosureForNode(c, childNode, level);
-                childNode.depthFirstRest(preorder, level + 1, c);
-                if (!preorder) callClosureForNode(c, childNode, level);
-            }
-        }
-    }
-
-    /**
-     * Provides a collection of all the nodes in the tree
-     * using a breadth-first preorder traversal.
-     *
-     * @return the list of (breadth-first) ordered nodes
-     */
-    public List breadthFirst() {
-        return breadthFirst(true);
-    }
-
-    /**
-     * Provides a collection of all the nodes in the tree
-     * using a breadth-first traversal.
-     *
-     * @param preorder if false, a postorder breadth-first traversal will be performed
-     * @return the list of (breadth-first) ordered nodes
-     * @since 2.5.0
-     */
-    public List breadthFirst(boolean preorder) {
-        List answer = new NodeList();
-        if (preorder) answer.add(this);
-        answer.addAll(breadthFirstRest(preorder));
-        if (!preorder) answer.add(this);
-        return answer;
-    }
-
-    private List breadthFirstRest(boolean preorder) {
-        List answer = new NodeList();
-        Stack stack = new Stack();
-        List nextLevelChildren = preorder ? getDirectChildren() : DefaultGroovyMethods.reverse(getDirectChildren());
-        while (!nextLevelChildren.isEmpty()) {
-            List working = new NodeList(nextLevelChildren);
-            nextLevelChildren = new NodeList();
-            for (Object child : working) {
-                if (preorder) {
-                    answer.add(child);
-                } else {
-                    stack.push(child);
-                }
-                if (child instanceof Node) {
-                    Node childNode = (Node) child;
-                    List children = childNode.getDirectChildren();
-                    if (children.size() > 1 || (children.size() == 1 && !(children.get(0) instanceof String))) nextLevelChildren.addAll(preorder ? children : DefaultGroovyMethods.reverse(children));
-                }
-            }
-        }
-        while (!stack.isEmpty()) {
-            answer.add(stack.pop());
-        }
-        return answer;
-    }
-
-    /**
-     * Calls the provided closure for all the nodes in the tree
-     * using a breadth-first preorder traversal.
-     *
-     * @param c the closure to run for each node (a one or two parameter can be used; if one parameter is given the
-     *          closure will be passed the node, for a two param closure the second parameter will be the level).
-     * @since 2.5.0
-     */
-    public void breadthFirst(Closure c) {
-        Map<String, Object> options = new ListHashMap<String, Object>();
-        options.put("preorder", true);
-        breadthFirst(options, c);
-    }
-
-    /**
-     * Calls the provided closure for all the nodes in the tree
-     * using a breadth-first traversal.
-     * A boolean 'preorder' options is supported.
-     *
-     * @param options map containing options
-     * @param c the closure to run for each node (a one or two parameter can be used; if one parameter is given the
-     *          closure will be passed the node, for a two param closure the second parameter will be the level).
-     * @since 2.5.0
-     */
-    public void breadthFirst(Map<String, Object> options, Closure c) {
-        boolean preorder = Boolean.valueOf(options.get("preorder").toString());
-        if (preorder) callClosureForNode(c, this, 1);
-        breadthFirstRest(preorder, 2, c);
-        if (!preorder) callClosureForNode(c, this, 1);
-    }
-
-    private void breadthFirstRest(boolean preorder, int level, Closure c) {
-        Stack<Tuple2<Object, Integer>> stack = new Stack<Tuple2<Object, Integer>>();
-        List nextLevelChildren = preorder ? getDirectChildren() : DefaultGroovyMethods.reverse(getDirectChildren());
-        while (!nextLevelChildren.isEmpty()) {
-            List working = new NodeList(nextLevelChildren);
-            nextLevelChildren = new NodeList();
-            for (Object child : working) {
-                if (preorder) {
-                    callClosureForNode(c, child, level);
-                } else {
-                    stack.push(new Tuple2<Object, Integer>(child, level));
-                }
-                if (child instanceof Node) {
-                    Node childNode = (Node) child;
-                    List children = childNode.getDirectChildren();
-                    if (children.size() > 1 || (children.size() == 1 && !(children.get(0) instanceof String))) nextLevelChildren.addAll(preorder ? children : DefaultGroovyMethods.reverse(children));
-                }
-            }
-            level++;
-        }
-        while (!stack.isEmpty()) {
-            Tuple2<Object, Integer> next = stack.pop();
-            callClosureForNode(c, next.getFirst(), next.getSecond());
-        }
-    }
-
-    /**
-     * Returns the list of any direct String nodes of this node.
-     *
-     * @return the list of String values from this node
-     * @since 2.3.0
-     */
-    public List<String> localText() {
-        List<String> answer = new ArrayList<String>();
-        for (Iterator iter = InvokerHelper.asIterator(value); iter.hasNext(); ) {
-            Object child = iter.next();
-            if (!(child instanceof Node)) {
-                answer.add(child.toString());
-            }
-        }
-        return answer;
-    }
-
-    private List getDirectChildren() {
-        List answer = new NodeList();
-        for (Iterator iter = InvokerHelper.asIterator(value); iter.hasNext(); ) {
-            Object child = iter.next();
-            if (child instanceof Node) {
-                Node childNode = (Node) child;
-                answer.add(childNode);
-            } else if (child instanceof String) {
-                answer.add(child);
-            }
-        }
-        return answer;
-    }
-
-    public String toString() {
-        return name + "[attributes=" + attributes + "; value=" + value + "]";
-    }
-
-    /**
-     * Writes the node to the specified <code>PrintWriter</code>.
-     *
-     * @param out the writer receiving the output
-     */
-    public void print(PrintWriter out) {
-        new NodePrinter(out).print(this);
-    }
-}

http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/util/NodeBuilder.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/util/NodeBuilder.java b/src/main/groovy/util/NodeBuilder.java
deleted file mode 100644
index babe5c3..0000000
--- a/src/main/groovy/util/NodeBuilder.java
+++ /dev/null
@@ -1,57 +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 groovy.util;
-
-import java.util.Map;
-
-/**
- * A helper class for creating nested trees of Node objects for 
- * handling arbitrary data
- * 
- * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
- */
-public class NodeBuilder extends BuilderSupport {
-
-    public static NodeBuilder newInstance() {
-        return new NodeBuilder();
-    }
-
-    protected void setParent(Object parent, Object child) {
-    }
-
-    protected Object createNode(Object name) {
-        return new Node(getCurrentNode(), name);
-    }
-
-    protected Object createNode(Object name, Object value) {
-        return new Node(getCurrentNode(), name, value);
-    }
-
-    protected Object createNode(Object name, Map attributes) {
-        return new Node(getCurrentNode(), name, attributes);
-    }
-
-    protected Object createNode(Object name, Map attributes, Object value) {
-        return new Node(getCurrentNode(), name, attributes, value);
-    }
-
-    protected Node getCurrentNode() {
-        return (Node) getCurrent();
-    }
-}

http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/util/NodeList.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/util/NodeList.java b/src/main/groovy/util/NodeList.java
deleted file mode 100644
index e54009c..0000000
--- a/src/main/groovy/util/NodeList.java
+++ /dev/null
@@ -1,202 +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 groovy.util;
-
-import groovy.lang.Closure;
-import groovy.lang.DelegatingMetaClass;
-import groovy.lang.GroovyRuntimeException;
-import groovy.lang.GroovySystem;
-import groovy.lang.MetaClass;
-import groovy.xml.QName;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * A List implementation which is returned by queries on a {@link Node}
- * which provides some XPath like helper methods for GPath.
- *
- * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
- * @author Paul King
- */
-public class NodeList extends ArrayList {
-    static {
-        // wrap the standard MetaClass with the delegate
-        setMetaClass(NodeList.class, GroovySystem.getMetaClassRegistry().getMetaClass(NodeList.class));
-    }
-
-    public NodeList() {
-    }
-
-    public NodeList(Collection collection) {
-        super(collection);
-    }
-
-    public NodeList(int size) {
-        super(size);
-    }
-
-    /**
-     * Creates a new NodeList containing the same elements as the
-     * original (but cloned in the case of Nodes).
-     *
-     * @return the clone
-     */
-    @Override
-    public Object clone() {
-        NodeList result = new NodeList(size());
-        for (int i = 0; i < size(); i++) {
-            Object next = get(i);
-            if (next instanceof Node) {
-                Node n = (Node) next;
-                result.add(n.clone());
-            } else {
-                result.add(next);
-            }
-        }
-        return result;
-    }
-
-    protected static void setMetaClass(final Class nodelistClass, final MetaClass metaClass) {
-        final MetaClass newMetaClass = new DelegatingMetaClass(metaClass) {
-            @Override
-            public Object getAttribute(final Object object, final String attribute) {
-                NodeList nl = (NodeList) object;
-                Iterator it = nl.iterator();
-                List result = new ArrayList();
-                while (it.hasNext()) {
-                    Node node = (Node) it.next();
-                    result.add(node.attributes().get(attribute));
-                }
-                return result;
-            }
-
-            @Override
-            public void setAttribute(final Object object, final String attribute, final Object newValue) {
-                for (Object o : (NodeList) object) {
-                    Node node = (Node) o;
-                    node.attributes().put(attribute, newValue);
-                }
-            }
-
-            @Override
-            public Object getProperty(Object object, String property) {
-                if (object instanceof NodeList) {
-                    NodeList nl = (NodeList) object;
-                    return nl.getAt(property);
-                }
-                return super.getProperty(object, property);
-            }
-        };
-        GroovySystem.getMetaClassRegistry().setMetaClass(nodelistClass, newMetaClass);
-    }
-
-    /**
-     * Provides lookup of elements by non-namespaced name.
-     *
-     * @param name the name or shortcut key for nodes of interest
-     * @return the nodes of interest which match name
-     */
-    public NodeList getAt(String name) {
-        NodeList answer = new NodeList();
-        for (Object child : this) {
-            if (child instanceof Node) {
-                Node childNode = (Node) child;
-                Object temp = childNode.get(name);
-                if (temp instanceof Collection) {
-                    answer.addAll((Collection) temp);
-                } else {
-                    answer.add(temp);
-                }
-            }
-        }
-        return answer;
-    }
-
-    /**
-     * Provides lookup of elements by QName.
-     *
-     * @param name the name or shortcut key for nodes of interest
-     * @return the nodes of interest which match name
-     */
-    public NodeList getAt(QName name) {
-        NodeList answer = new NodeList();
-        for (Object child : this) {
-            if (child instanceof Node) {
-                Node childNode = (Node) child;
-                NodeList temp = childNode.getAt(name);
-                answer.addAll(temp);
-            }
-        }
-        return answer;
-    }
-
-    /**
-     * Returns the text value of all of the elements in the collection.
-     *
-     * @return the text value of all the elements in the collection or null
-     */
-    public String text() {
-        String previousText = null;
-        StringBuilder buffer = null;
-        for (Object child : this) {
-            String text = null;
-            if (child instanceof String) {
-                text = (String) child;
-            } else if (child instanceof Node) {
-                text = ((Node) child).text();
-            }
-            if (text != null) {
-                if (previousText == null) {
-                    previousText = text;
-                } else {
-                    if (buffer == null) {
-                        buffer = new StringBuilder();
-                        buffer.append(previousText);
-                    }
-                    buffer.append(text);
-                }
-            }
-        }
-        if (buffer != null) {
-            return buffer.toString();
-        }
-        if (previousText != null) {
-            return previousText;
-        }
-        return "";
-    }
-
-    public Node replaceNode(Closure c) {
-        if (size() <= 0 || size() > 1) {
-            throw new GroovyRuntimeException(
-                    "replaceNode() can only be used to replace a single node, but was applied to " + size() + " nodes");
-        }
-        return ((Node)get(0)).replaceNode(c);
-    }
-
-    public void plus(Closure c) {
-        for (Object o : this) {
-            ((Node) o).plus(c);
-        }
-    }
-
-}