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 04:29:30 UTC

[22/47] groovy git commit: Move source files to proper packages

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/util/PermutationGenerator.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/PermutationGenerator.java b/src/main/groovy/groovy/util/PermutationGenerator.java
new file mode 100644
index 0000000..a9b68e2
--- /dev/null
+++ b/src/main/groovy/groovy/util/PermutationGenerator.java
@@ -0,0 +1,149 @@
+/*
+ *  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 java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Systematically generate permutations.
+ *
+ * Adapted from Java Code by Michael Gilleland (released with no restrictions) using an algorithm described here:
+ * Kenneth H. Rosen, Discrete Mathematics and Its Applications, 2nd edition (NY: McGraw-Hill, 1991), pp. 282-284
+ */
+public class PermutationGenerator<E> implements Iterator<List<E>> {
+    private final int[] a;
+    private BigInteger numLeft;
+    private final BigInteger total;
+    private final List<E> items;
+
+    /**
+     * WARNING: Don't make n too large.
+     * Recall that the number of permutations is n!
+     * which can be very large, even when n is as small as 20 --
+     * 20! = 2,432,902,008,176,640,000 and
+     * 21! is too big to fit into a Java long, which is
+     * why we use BigInteger instead.
+     *
+     * @param items the items to permute
+     */
+    public PermutationGenerator(Collection<E> items) {
+        this.items = new ArrayList<E>(items);
+        int n = items.size();
+        if (n < 1) {
+            throw new IllegalArgumentException("At least one item required");
+        }
+        a = new int[n];
+        total = getFactorial(n);
+        reset();
+    }
+
+    public PermutationGenerator(Iterable<E> items) {
+        this(DefaultGroovyMethods.asCollection(items));
+    }
+
+    public void reset() {
+        for (int i = 0; i < a.length; i++) {
+            a[i] = i;
+        }
+        numLeft = new BigInteger(total.toString());
+    }
+
+    public BigInteger getTotal() {
+        return total;
+    }
+
+    public boolean hasNext() {
+        return numLeft.compareTo(BigInteger.ZERO) == 1;
+    }
+
+    /**
+     * Compute factorial (TODO: expose this)
+     *
+     * @param n the input integer
+     * @return the factorial for n
+     */
+    private static BigInteger getFactorial(int n) {
+        BigInteger fact = BigInteger.ONE;
+        for (int i = n; i > 1; i--) {
+            fact = fact.multiply(new BigInteger(Integer.toString(i)));
+        }
+        return fact;
+    }
+
+    /**
+     * Generate next permutation (algorithm from Rosen p. 284)
+     *
+     * @return the items permuted
+     */
+    public List<E> next() {
+        if (numLeft.equals(total)) {
+            numLeft = numLeft.subtract(BigInteger.ONE);
+            return items;
+        }
+
+        int temp;
+
+        // Find largest index j with a[j] < a[j+1]
+        int j = a.length - 2;
+        while (a[j] > a[j + 1]) {
+            j--;
+        }
+
+        // Find index k such that a[k] is smallest integer
+        // greater than a[j] to the right of a[j]
+        int k = a.length - 1;
+        while (a[j] > a[k]) {
+            k--;
+        }
+
+        // Interchange a[j] and a[k]
+        temp = a[k];
+        a[k] = a[j];
+        a[j] = temp;
+
+        // Put tail end of permutation after jth position in increasing order
+        int r = a.length - 1;
+        int s = j + 1;
+
+        while (r > s) {
+            temp = a[s];
+            a[s] = a[r];
+            a[r] = temp;
+            r--;
+            s++;
+        }
+
+        numLeft = numLeft.subtract(BigInteger.ONE);
+        List<E> ans = new ArrayList<E>(a.length);
+        for (int index : a) {
+            ans.add(items.get(index));
+        }
+        return ans;
+    }
+
+    public void remove() {
+        throw new UnsupportedOperationException("remove() not allowed for PermutationGenerator");
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/util/Proxy.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/Proxy.java b/src/main/groovy/groovy/util/Proxy.java
new file mode 100644
index 0000000..ac080b3
--- /dev/null
+++ b/src/main/groovy/groovy/util/Proxy.java
@@ -0,0 +1,70 @@
+/*
+ *  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.GroovyObjectSupport;
+import groovy.lang.MissingMethodException;
+import org.codehaus.groovy.runtime.InvokerHelper;
+
+import java.util.Iterator;
+
+/**
+ * Dynamic groovy proxy for another object.  All method
+ * invocations get forwarded to actual object, unless the proxy overrides it.
+ * See groovy/util/ProxyTest.groovy for usage details.
+ *
+ * @author Troy Heninger
+ * @author Dierk Koenig
+ */
+public class Proxy extends GroovyObjectSupport {
+
+    private Object adaptee = null;
+
+    /**
+     * This method is for convenience.
+     * It allows to get around the need for defining dump ctors in subclasses.
+     * See unit tests for details.
+     */
+    public Proxy wrap(Object adaptee){
+        setAdaptee(adaptee);
+        return this;
+    }
+
+    public Object getAdaptee() {
+        return adaptee;
+    }
+
+    public void setAdaptee(Object adaptee) {
+        this.adaptee = adaptee;
+    }
+
+    public Object invokeMethod(String name, Object args) {
+        try {
+            return super.invokeMethod(name, args);
+        }
+        catch (MissingMethodException e) {
+            return InvokerHelper.invokeMethod(adaptee, name, args);
+        }
+    }
+    
+    public Iterator iterator() {
+        return InvokerHelper.asIterator(adaptee);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/util/ProxyGenerator.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/ProxyGenerator.java b/src/main/groovy/groovy/util/ProxyGenerator.java
new file mode 100644
index 0000000..da12b97
--- /dev/null
+++ b/src/main/groovy/groovy/util/ProxyGenerator.java
@@ -0,0 +1,339 @@
+/*
+ *  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.GroovyObject;
+import groovy.lang.GroovySystem;
+import groovy.lang.MetaClass;
+import org.codehaus.groovy.runtime.InvokerHelper;
+import org.codehaus.groovy.runtime.ProxyGeneratorAdapter;
+import org.codehaus.groovy.runtime.memoize.LRUCache;
+import org.codehaus.groovy.runtime.typehandling.GroovyCastException;
+import org.codehaus.groovy.transform.trait.Traits;
+
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Classes to generate 'Proxy' objects which implement interfaces,
+ * maps of closures and/or extend classes/delegates.
+ *
+ * @author Paul King
+ * @author Guillaume Laforge
+ * @author Cedric Champeau
+ */
+public class ProxyGenerator {
+    private static final Class[] EMPTY_CLASS_ARRAY = new Class[0];
+    private static final Class[] EMPTY_INTERFACE_ARRAY = EMPTY_CLASS_ARRAY;
+    private static final Map<Object,Object> EMPTY_CLOSURE_MAP = Collections.emptyMap();
+    private static final Set<String> EMPTY_KEYSET = Collections.emptySet();
+
+    public static final ProxyGenerator INSTANCE = new ProxyGenerator();
+
+    static {
+        // wrap the standard MetaClass with the delegate
+        setMetaClass(GroovySystem.getMetaClassRegistry().getMetaClass(ProxyGenerator.class));
+    }
+
+    private ClassLoader override = null;
+    private boolean debug = false;
+    private boolean emptyMethods = false;
+
+    /**
+     * The adapter cache is used to cache proxy classes. When, for example, a call like:
+     * map as MyClass is found, then a lookup is made into the cache to find if a suitable
+     * adapter already exists. If so, then the class is reused, instead of generating a
+     * new class.
+     */
+    private final LRUCache adapterCache = new LRUCache(16);
+
+    public boolean getDebug() {
+        return debug;
+    }
+
+    /**
+     * Instructs <code>ProxyGenerator</code> to dump generated Groovy
+     * source code to standard output during construction. This is useful
+     * for debugging purposes but should be turned off in production.
+     *
+     * @param debug true if you want generated source to be printed
+     */
+    public void setDebug(boolean debug) {
+        this.debug = debug;
+    }
+
+    public boolean getEmptyMethods() {
+        return emptyMethods;
+    }
+
+    /**
+     * Changes generated methods to have empty implementations.
+     * <p>
+     * Methods in generated aggregates not supplied in a closures map or
+     * base class are given 'default' implementations. The implementation
+     * will normally throw an <code>UnsupportedOperationException</code>
+     * but setting this boolean will leave it empty.
+     *
+     * @param emptyMethods true if you want generated methods to be empty
+     */
+    public void setEmptyMethods(boolean emptyMethods) {
+        this.emptyMethods = emptyMethods;
+    }
+
+    public ClassLoader getOverride() {
+        return override;
+    }
+
+    public void setOverride(ClassLoader override) {
+        this.override = override;
+    }
+
+    public GroovyObject instantiateAggregateFromBaseClass(Class clazz) {
+        return instantiateAggregateFromBaseClass((Map) null, clazz);
+    }
+
+    public GroovyObject instantiateAggregateFromBaseClass(Map map, Class clazz) {
+        return instantiateAggregateFromBaseClass(map, clazz, null);
+    }
+
+    public GroovyObject instantiateAggregateFromBaseClass(Closure cl, Class clazz) {
+        Map<String, Closure> m = new HashMap<String, Closure>();
+        m.put("*", cl);
+        return instantiateAggregateFromBaseClass(m, clazz, null);
+    }
+
+    public GroovyObject instantiateAggregateFromBaseClass(Class clazz, Object[] constructorArgs) {
+        return instantiateAggregate(null, null, clazz, constructorArgs);
+    }
+
+    public GroovyObject instantiateAggregateFromBaseClass(Map map, Class clazz, Object[] constructorArgs) {
+        return instantiateAggregate(map, null, clazz, constructorArgs);
+    }
+
+    public GroovyObject instantiateAggregateFromInterface(Class clazz) {
+        return instantiateAggregateFromInterface(null, clazz);
+    }
+
+    public GroovyObject instantiateAggregateFromInterface(Map map, Class clazz) {
+        List<Class> interfaces = new ArrayList<Class>();
+        interfaces.add(clazz);
+        return instantiateAggregate(map, interfaces);
+    }
+
+    public GroovyObject instantiateAggregate(List<Class> interfaces) {
+        return instantiateAggregate(null, interfaces);
+    }
+
+    public GroovyObject instantiateAggregate(Map closureMap, List<Class> interfaces) {
+        return instantiateAggregate(closureMap, interfaces, null);
+    }
+
+    public GroovyObject instantiateAggregate(Map closureMap, List<Class> interfaces, Class clazz) {
+        return instantiateAggregate(closureMap, interfaces, clazz, null);
+    }
+
+    @SuppressWarnings("unchecked")
+    public GroovyObject instantiateAggregate(Map closureMap, List<Class> interfaces, Class clazz, Object[] constructorArgs) {
+        if (clazz != null && Modifier.isFinal(clazz.getModifiers())) {
+            throw new GroovyCastException("Cannot coerce a map to class " + clazz.getName() + " because it is a final class");
+        }
+        Map<Object,Object> map = closureMap != null ? closureMap : EMPTY_CLOSURE_MAP;
+        ProxyGeneratorAdapter adapter = createAdapter(map, interfaces, null, clazz);
+
+        return adapter.proxy(map, constructorArgs);
+    }
+
+    public GroovyObject instantiateDelegate(Object delegate) {
+        return instantiateDelegate(null, delegate);
+    }
+
+    public GroovyObject instantiateDelegate(List<Class> interfaces, Object delegate) {
+        return instantiateDelegate(null, interfaces, delegate);
+    }
+
+    public GroovyObject instantiateDelegate(Map closureMap, List<Class> interfaces, Object delegate) {
+        return instantiateDelegateWithBaseClass(closureMap, interfaces, delegate, null);
+    }
+
+    public GroovyObject instantiateDelegateWithBaseClass(Map closureMap, List<Class> interfaces, Object delegate) {
+        return instantiateDelegateWithBaseClass(closureMap, interfaces, delegate, delegate.getClass());
+    }
+
+    public GroovyObject instantiateDelegateWithBaseClass(Map closureMap, List<Class> interfaces, Object delegate, Class baseClass) {
+        return instantiateDelegateWithBaseClass(closureMap, interfaces, delegate, baseClass, null);
+    }
+
+    /**
+     * Creates a proxy with a delegate object.
+     *
+     * @param closureMap the closure for methods not handled by the delegate
+     * @param interfaces interfaces to be implemented
+     * @param delegate the delegate object
+     * @param baseClass the base class
+     * @param name the name of the proxy, unused, but kept for compatibility with previous versions of Groovy.
+     * @return a proxy object implementing the specified interfaces, and delegating to the provided object
+     */
+    @SuppressWarnings("unchecked")
+    public GroovyObject instantiateDelegateWithBaseClass(Map closureMap, List<Class> interfaces, Object delegate, Class baseClass, String name) {
+        Map<Object,Object> map = closureMap != null ? closureMap : EMPTY_CLOSURE_MAP;
+        ProxyGeneratorAdapter adapter = createAdapter(map, interfaces, delegate.getClass(), baseClass);
+
+        return adapter.delegatingProxy(delegate, map, (Object[])null);
+    }
+
+    private ProxyGeneratorAdapter createAdapter(Map closureMap, List<Class> interfaces, Class delegateClass, Class baseClass) {
+        // According to https://shipilev.net/blog/2016/arrays-wisdom-ancients/#_conclusion
+        // toArray(new T[0]) seems faster, safer, and contractually cleaner, and therefore should be the default choice now.
+        Class[] intfs = interfaces != null ? interfaces.toArray(EMPTY_CLASS_ARRAY) : EMPTY_INTERFACE_ARRAY;
+        Class base = baseClass;
+        if (base == null) {
+            if (intfs.length > 0) {
+                base = intfs[0];
+            } else {
+                base = Object.class;
+            }
+        }
+        Set<String> keys = closureMap == EMPTY_CLOSURE_MAP ? EMPTY_KEYSET : new HashSet<String>();
+        for (Object o : closureMap.keySet()) {
+            keys.add(o.toString());
+        }
+        boolean useDelegate = null != delegateClass;
+        CacheKey key = new CacheKey(base, useDelegate ? delegateClass : Object.class, keys, intfs, emptyMethods, useDelegate);
+        ProxyGeneratorAdapter adapter = (ProxyGeneratorAdapter) adapterCache.get(key);
+        if (adapter == null) {
+            adapter = new ProxyGeneratorAdapter(closureMap, base, intfs, useDelegate ? delegateClass.getClassLoader() : base.getClassLoader(), emptyMethods, useDelegate ? delegateClass : null);
+            adapterCache.put(key, adapter);
+        }
+
+        return adapter;
+    }
+
+    private static void setMetaClass(final MetaClass metaClass) {
+        final MetaClass newMetaClass = new DelegatingMetaClass(metaClass) {
+            @Override
+            public Object invokeStaticMethod(Object object, String methodName, Object[] arguments) {
+                return InvokerHelper.invokeMethod(INSTANCE, methodName, arguments);
+            }
+        };
+        GroovySystem.getMetaClassRegistry().setMetaClass(ProxyGenerator.class, newMetaClass);
+    }
+    
+    private static final class CacheKey {
+        private static final Comparator<Class> INTERFACE_COMPARATOR = new Comparator<Class>() {
+            public int compare(final Class o1, final Class o2) {
+                // Traits order *must* be preserved
+                // See GROOVY-7285
+                if (Traits.isTrait(o1)) return -1;
+                if (Traits.isTrait(o2)) return 1;
+                return o1.getName().compareTo(o2.getName());
+            }
+        };
+        private final boolean emptyMethods;
+        private final boolean useDelegate;
+        private final Set<String> methods;
+        private final ClassReference delegateClass;
+        private final ClassReference baseClass;
+        private final ClassReference[] interfaces;
+
+        private CacheKey(final Class baseClass, final Class delegateClass, final Set<String> methods, final Class[] interfaces, final boolean emptyMethods, final boolean useDelegate) {
+            this.useDelegate = useDelegate;
+            this.baseClass = new ClassReference(baseClass);
+            this.delegateClass = new ClassReference(delegateClass);
+            this.emptyMethods = emptyMethods;
+            this.interfaces = interfaces == null ? null : new ClassReference[interfaces.length];
+            if (interfaces != null) {
+                Class[] interfacesCopy = new Class[interfaces.length];
+                System.arraycopy(interfaces, 0, interfacesCopy, 0, interfaces.length);
+                Arrays.sort(interfacesCopy, INTERFACE_COMPARATOR);
+                for (int i = 0; i < interfacesCopy.length; i++) {
+                    Class anInterface = interfacesCopy[i];
+                    this.interfaces[i] = new ClassReference(anInterface);
+                }
+            }
+            this.methods = methods;
+        }
+
+        @Override
+        public boolean equals(final Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            final CacheKey cacheKey = (CacheKey) o;
+
+            if (emptyMethods != cacheKey.emptyMethods) return false;
+            if (useDelegate != cacheKey.useDelegate) return false;
+            if (baseClass != null ? !baseClass.equals(cacheKey.baseClass) : cacheKey.baseClass != null) return false;
+            if (delegateClass != null ? !delegateClass.equals(cacheKey.delegateClass) : cacheKey.delegateClass != null) return false;
+            if (!Arrays.equals(interfaces, cacheKey.interfaces)) return false;
+            if (methods != null ? !methods.equals(cacheKey.methods) : cacheKey.methods != null) return false;
+
+            return true;
+        }
+
+        @Override
+        public int hashCode() {
+            int result = (emptyMethods ? 1 : 0);
+            result = 31 * result + (useDelegate ? 1 : 0);
+            result = 31 * result + (methods != null ? methods.hashCode() : 0);
+            result = 31 * result + (baseClass != null ? baseClass.hashCode() : 0);
+            result = 31 * result + (delegateClass != null ? delegateClass.hashCode() : 0);
+            result = 31 * result + (interfaces != null ? Arrays.hashCode(interfaces) : 0);
+            return result;
+        }
+
+        /**
+         * A weak reference which delegates equals and hashcode to the referent.
+         */
+        private static class ClassReference extends WeakReference<Class> {
+
+            public ClassReference(Class referent) {
+                super(referent);
+            }
+
+            @Override
+            public boolean equals(final Object o) {
+                if (this == o) return true;
+                if (o == null || getClass() != o.getClass()) return false;
+                Class thisClass = this.get();
+                ClassReference that = (ClassReference) o;
+                if (thisClass == null) return false;
+                return thisClass.equals(that.get());
+            }
+
+            @Override
+            public int hashCode() {
+                Class thisClass = this.get();
+                if (thisClass == null) return 0;
+                return thisClass.hashCode();
+            }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/util/ResourceConnector.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/ResourceConnector.java b/src/main/groovy/groovy/util/ResourceConnector.java
new file mode 100644
index 0000000..81e329a
--- /dev/null
+++ b/src/main/groovy/groovy/util/ResourceConnector.java
@@ -0,0 +1,37 @@
+/*
+ *  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.net.URLConnection;
+
+/**
+ * Base interface for customizing where resources can be found for the <code>GroovyScriptEngine</code>.
+ *
+ * @author sam
+ */
+public interface ResourceConnector {
+
+    /**
+     * Retrieve a URLConnection to a script referenced by name.
+     *
+     * @param name
+     * @throws ResourceException
+     */
+    URLConnection getResourceConnection(String name) throws ResourceException;
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/util/ResourceException.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/ResourceException.java b/src/main/groovy/groovy/util/ResourceException.java
new file mode 100644
index 0000000..8b31d7e
--- /dev/null
+++ b/src/main/groovy/groovy/util/ResourceException.java
@@ -0,0 +1,56 @@
+/*
+ *  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;
+
+/**
+ * @author sam
+ */
+public class ResourceException extends Exception {
+
+    /**
+     *
+     */
+    public ResourceException() {
+        super();
+        // TODO Auto-generated constructor stub
+    }
+
+    /**
+     * @param message
+     */
+    public ResourceException(String message) {
+        super(message);
+    }
+
+    /**
+     * @param message
+     * @param cause
+     */
+    public ResourceException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * @param cause
+     */
+    public ResourceException(Throwable cause) {
+        super(cause);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/util/ScriptException.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/ScriptException.java b/src/main/groovy/groovy/util/ScriptException.java
new file mode 100644
index 0000000..85ce60f
--- /dev/null
+++ b/src/main/groovy/groovy/util/ScriptException.java
@@ -0,0 +1,55 @@
+/*
+ *  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;
+
+/**
+ * @author sam
+ */
+public class ScriptException extends Exception {
+
+    /**
+     *
+     */
+    public ScriptException() {
+        super();
+    }
+
+    /**
+     * @param message
+     */
+    public ScriptException(String message) {
+        super(message);
+    }
+
+    /**
+     * @param message
+     * @param cause
+     */
+    public ScriptException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * @param cause
+     */
+    public ScriptException(Throwable cause) {
+        super(cause);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/util/logging/Commons.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/logging/Commons.java b/src/main/groovy/groovy/util/logging/Commons.java
new file mode 100644
index 0000000..aa456d2
--- /dev/null
+++ b/src/main/groovy/groovy/util/logging/Commons.java
@@ -0,0 +1,108 @@
+/*
+ *  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.logging;
+
+import groovy.lang.GroovyClassLoader;
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.FieldNode;
+import org.codehaus.groovy.ast.expr.ArgumentListExpression;
+import org.codehaus.groovy.ast.expr.BooleanExpression;
+import org.codehaus.groovy.ast.expr.ClassExpression;
+import org.codehaus.groovy.ast.expr.ConstantExpression;
+import org.codehaus.groovy.ast.expr.Expression;
+import org.codehaus.groovy.ast.expr.MethodCallExpression;
+import org.codehaus.groovy.ast.expr.TernaryExpression;
+import org.codehaus.groovy.transform.GroovyASTTransformationClass;
+import org.codehaus.groovy.transform.LogASTTransformation;
+import org.objectweb.asm.Opcodes;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.Locale;
+
+/**
+ * This local transform adds a logging ability to your program using
+ * Apache Commons logging. Every method call on a unbound variable named <i>log</i>
+ * will be mapped to a call to the logger. For this a <i>log</i> field will be
+ * inserted in the class. If the field already exists the usage of this transform
+ * will cause a compilation error. The method name will be used to determine
+ * what to call on the logger.
+ * <pre>
+ * log.name(exp)
+ * </pre>is mapped to
+ * <pre>
+ * if (log.isNameEnabled() {
+ *    log.name(exp)
+ * }</pre>
+ * Here name is a place holder for info, debug, warning, error, etc.
+ * If the expression exp is a constant or only a variable access the method call will
+ * not be transformed. But this will still cause a call on the injected logger.
+ *
+ * @author Hamlet D'Arcy
+ * @author Matthias Cullmann
+ * @since 1.8.0
+ */
+@java.lang.annotation.Documented
+@Retention(RetentionPolicy.SOURCE)
+@Target({ElementType.TYPE})
+@GroovyASTTransformationClass("org.codehaus.groovy.transform.LogASTTransformation")
+public @interface Commons {
+    String value() default "log";
+    String category() default LogASTTransformation.DEFAULT_CATEGORY_NAME;
+    Class<? extends LogASTTransformation.LoggingStrategy> loggingStrategy() default CommonsLoggingStrategy.class;
+
+    public  static class CommonsLoggingStrategy extends LogASTTransformation.AbstractLoggingStrategy {
+
+        private static final String LOGGER_NAME = "org.apache.commons.logging.Log";
+        private static final String LOGGERFACTORY_NAME = "org.apache.commons.logging.LogFactory";
+
+        protected CommonsLoggingStrategy(final GroovyClassLoader loader) {
+            super(loader);
+        }
+
+        public FieldNode addLoggerFieldToClass(ClassNode classNode, String logFieldName, String categoryName) {
+            return classNode.addField(logFieldName,
+                    Opcodes.ACC_FINAL | Opcodes.ACC_TRANSIENT | Opcodes.ACC_STATIC | Opcodes.ACC_PRIVATE,
+                    classNode(LOGGER_NAME),
+                    new MethodCallExpression(
+                            new ClassExpression(classNode(LOGGERFACTORY_NAME)),
+                            "getLog",
+                            new ConstantExpression(getCategoryName(classNode, categoryName))));
+        }
+
+        public boolean isLoggingMethod(String methodName) {
+            return methodName.matches("fatal|error|warn|info|debug|trace");
+        }
+
+        public Expression wrapLoggingMethodCall(Expression logVariable, String methodName, Expression originalExpression) {
+            MethodCallExpression condition = new MethodCallExpression(
+                    logVariable,
+                    "is" + methodName.substring(0, 1).toUpperCase(Locale.ENGLISH) + methodName.substring(1, methodName.length()) + "Enabled",
+                    ArgumentListExpression.EMPTY_ARGUMENTS);
+            condition.setImplicitThis(false);
+
+            return new TernaryExpression(
+                    new BooleanExpression(condition),
+                    originalExpression,
+                    ConstantExpression.NULL);
+        }
+   }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/util/logging/Log.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/logging/Log.java b/src/main/groovy/groovy/util/logging/Log.java
new file mode 100644
index 0000000..e52d39b
--- /dev/null
+++ b/src/main/groovy/groovy/util/logging/Log.java
@@ -0,0 +1,124 @@
+/*
+ *  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.logging;
+
+import groovy.lang.GroovyClassLoader;
+import org.codehaus.groovy.ast.ClassHelper;
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.FieldNode;
+import org.codehaus.groovy.ast.expr.ArgumentListExpression;
+import org.codehaus.groovy.ast.expr.AttributeExpression;
+import org.codehaus.groovy.ast.expr.BooleanExpression;
+import org.codehaus.groovy.ast.expr.ClassExpression;
+import org.codehaus.groovy.ast.expr.ConstantExpression;
+import org.codehaus.groovy.ast.expr.Expression;
+import org.codehaus.groovy.ast.expr.MethodCallExpression;
+import org.codehaus.groovy.ast.expr.TernaryExpression;
+import org.codehaus.groovy.transform.GroovyASTTransformationClass;
+import org.codehaus.groovy.transform.LogASTTransformation;
+import org.codehaus.groovy.transform.LogASTTransformation.LoggingStrategy;
+import org.objectweb.asm.Opcodes;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.Locale;
+
+/**
+ * This local transform adds a logging ability to your program using
+ * java.util.logging. Every method call on a unbound variable named <i>log</i>
+ * will be mapped to a call to the logger. For this a <i>log</i> field will be
+ * inserted in the class. If the field already exists the usage of this transform
+ * will cause a compilation error. The method name will be used to determine
+ * what to call on the logger.
+ * <pre>
+ * log.name(exp)
+ * </pre>is mapped to
+ * <pre>
+ * if (log.isLoggable(Level.NAME) {
+ *    log.name(exp)
+ * }</pre>
+ * Here name is a place holder for info, fine, finer, finest, config, warning, severe.
+ * NAME is name transformed to upper case. if anything else is used it will result in
+ * an exception at runtime. If the expression exp is a constant or only a variable access
+ * the method call will not be transformed. But this will still cause a call on the injected
+ * logger.
+ *
+ * @author Guillaume Laforge
+ * @author Jochen Theodorou
+ * @author Dinko Srkoc
+ * @author Hamlet D'Arcy
+ * @author Raffaele Cigni
+ * @author Alberto Vilches Raton
+ * @since 1.8.0
+ */
+@java.lang.annotation.Documented
+@Retention(RetentionPolicy.SOURCE)
+@Target({ElementType.TYPE})
+@GroovyASTTransformationClass("org.codehaus.groovy.transform.LogASTTransformation")
+public @interface Log {
+    String value() default "log";
+    String category() default LogASTTransformation.DEFAULT_CATEGORY_NAME;
+    Class<? extends LoggingStrategy> loggingStrategy() default JavaUtilLoggingStrategy.class;
+
+    /**
+     * This class contains the logic of how to weave a Java Util Logging logger into the host class.
+     */
+    public static class JavaUtilLoggingStrategy extends LogASTTransformation.AbstractLoggingStrategy {
+
+        private static final ClassNode LOGGER_CLASSNODE = ClassHelper.make(java.util.logging.Logger.class);
+        private static final ClassNode LEVEL_CLASSNODE = ClassHelper.make(java.util.logging.Level.class);
+
+        protected JavaUtilLoggingStrategy(final GroovyClassLoader loader) {
+            super(loader);
+        }
+
+        public FieldNode addLoggerFieldToClass(ClassNode classNode, String logFieldName, String categoryName) {
+            return classNode.addField(logFieldName,
+                        Opcodes.ACC_FINAL | Opcodes.ACC_TRANSIENT | Opcodes.ACC_STATIC | Opcodes.ACC_PRIVATE,
+                        LOGGER_CLASSNODE,
+                        new MethodCallExpression(
+                                new ClassExpression(LOGGER_CLASSNODE),
+                                "getLogger",
+                                new ConstantExpression(getCategoryName(classNode, categoryName))));
+        }
+
+        public boolean isLoggingMethod(String methodName) {
+            return methodName.matches("severe|warning|info|fine|finer|finest");
+        }
+
+        public Expression wrapLoggingMethodCall(Expression logVariable, String methodName, Expression originalExpression) {
+            AttributeExpression logLevelExpression = new AttributeExpression(
+                    new ClassExpression(LEVEL_CLASSNODE),
+                    new ConstantExpression(methodName.toUpperCase(Locale.ENGLISH)));
+
+            ArgumentListExpression args = new ArgumentListExpression();
+            args.addExpression(logLevelExpression);
+            MethodCallExpression condition = new MethodCallExpression(logVariable, "isLoggable", args);
+            condition.setImplicitThis(false);
+
+            return new TernaryExpression(
+                    new BooleanExpression(condition),
+                    originalExpression,
+                    ConstantExpression.NULL);
+
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/util/logging/Log4j.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/logging/Log4j.java b/src/main/groovy/groovy/util/logging/Log4j.java
new file mode 100644
index 0000000..2dfdf7f
--- /dev/null
+++ b/src/main/groovy/groovy/util/logging/Log4j.java
@@ -0,0 +1,119 @@
+/*
+ *  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.logging;
+
+import groovy.lang.GroovyClassLoader;
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.FieldNode;
+import org.codehaus.groovy.ast.expr.ArgumentListExpression;
+import org.codehaus.groovy.ast.expr.AttributeExpression;
+import org.codehaus.groovy.ast.expr.BooleanExpression;
+import org.codehaus.groovy.ast.expr.ClassExpression;
+import org.codehaus.groovy.ast.expr.ConstantExpression;
+import org.codehaus.groovy.ast.expr.Expression;
+import org.codehaus.groovy.ast.expr.MethodCallExpression;
+import org.codehaus.groovy.ast.expr.TernaryExpression;
+import org.codehaus.groovy.transform.GroovyASTTransformationClass;
+import org.codehaus.groovy.transform.LogASTTransformation;
+import org.objectweb.asm.Opcodes;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.Locale;
+
+/**
+ * This local transform adds a logging ability to your program using
+ * Log4j logging. Every method call on a unbound variable named <i>log</i>
+ * will be mapped to a call to the logger. For this a <i>log</i> field will be
+ * inserted in the class. If the field already exists the usage of this transform
+ * will cause a compilation error. The method name will be used to determine
+ * what to call on the logger.
+ * <pre>
+ * log.name(exp)
+ * </pre>is mapped to
+ * <pre>
+ * if (log.isNameEnabled() {
+ *    log.name(exp)
+ * }</pre>
+ * Here name is a place holder for info, debug, warning, error, etc.
+ * If the expression exp is a constant or only a variable access the method call will
+ * not be transformed. But this will still cause a call on the injected logger.
+ *
+ * @author Hamlet D'Arcy
+ * @author Tomek Bujok
+ * @since 1.8.0
+ */
+@java.lang.annotation.Documented
+@Retention(RetentionPolicy.SOURCE)
+@Target({ElementType.TYPE})
+@GroovyASTTransformationClass("org.codehaus.groovy.transform.LogASTTransformation")
+public @interface Log4j {
+    String value() default "log";
+    String category() default LogASTTransformation.DEFAULT_CATEGORY_NAME;
+    Class<? extends LogASTTransformation.LoggingStrategy> loggingStrategy() default Log4jLoggingStrategy.class;
+
+    public static class Log4jLoggingStrategy extends LogASTTransformation.AbstractLoggingStrategy {
+        private static final String LOGGER_NAME = "org.apache.log4j.Logger";
+        private static final String PRIORITY_NAME = "org.apache.log4j.Priority";
+
+        protected Log4jLoggingStrategy(final GroovyClassLoader loader) {
+            super(loader);
+        }
+
+        public FieldNode addLoggerFieldToClass(ClassNode classNode, String logFieldName, String categoryName) {
+            return classNode.addField(logFieldName,
+                    Opcodes.ACC_FINAL | Opcodes.ACC_TRANSIENT | Opcodes.ACC_STATIC | Opcodes.ACC_PRIVATE,
+                    classNode(LOGGER_NAME),
+                    new MethodCallExpression(
+                            new ClassExpression(classNode(LOGGER_NAME)),
+                            "getLogger",
+                            new ConstantExpression(getCategoryName(classNode, categoryName))));
+        }
+
+        public boolean isLoggingMethod(String methodName) {
+            return methodName.matches("fatal|error|warn|info|debug|trace");
+        }
+
+        public Expression wrapLoggingMethodCall(Expression logVariable, String methodName, Expression originalExpression) {
+            final MethodCallExpression condition;
+            if (!"trace".equals(methodName)) {
+                AttributeExpression logLevelExpression = new AttributeExpression(
+                        new ClassExpression(classNode(PRIORITY_NAME)),
+                        new ConstantExpression(methodName.toUpperCase(Locale.ENGLISH)));
+                ArgumentListExpression args = new ArgumentListExpression();
+                args.addExpression(logLevelExpression);
+                condition = new MethodCallExpression(logVariable, "isEnabledFor", args);
+            } else {
+                // log4j api is inconsistent, so trace requires special handling
+                condition = new MethodCallExpression(
+                        logVariable,
+                        "is" + methodName.substring(0, 1).toUpperCase(Locale.ENGLISH) + methodName.substring(1, methodName.length()) + "Enabled",
+                        ArgumentListExpression.EMPTY_ARGUMENTS);
+            }
+            condition.setImplicitThis(false);
+
+            return new TernaryExpression(
+                    new BooleanExpression(condition),
+                    originalExpression,
+                    ConstantExpression.NULL);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/util/logging/Log4j2.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/logging/Log4j2.java b/src/main/groovy/groovy/util/logging/Log4j2.java
new file mode 100644
index 0000000..7aca5a5
--- /dev/null
+++ b/src/main/groovy/groovy/util/logging/Log4j2.java
@@ -0,0 +1,105 @@
+/*
+ *  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.logging;
+
+import groovy.lang.GroovyClassLoader;
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.FieldNode;
+import org.codehaus.groovy.ast.expr.ArgumentListExpression;
+import org.codehaus.groovy.ast.expr.BooleanExpression;
+import org.codehaus.groovy.ast.expr.ClassExpression;
+import org.codehaus.groovy.ast.expr.ConstantExpression;
+import org.codehaus.groovy.ast.expr.Expression;
+import org.codehaus.groovy.ast.expr.MethodCallExpression;
+import org.codehaus.groovy.ast.expr.TernaryExpression;
+import org.codehaus.groovy.transform.GroovyASTTransformationClass;
+import org.codehaus.groovy.transform.LogASTTransformation;
+import org.objectweb.asm.Opcodes;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.Locale;
+
+/**
+ * This local transform adds a logging ability to your program using
+ * Log4j2 logging. Every method call on a unbound variable named <i>log</i>
+ * will be mapped to a call to the logger. For this a <i>log</i> field will be
+ * inserted in the class. If the field already exists the usage of this transform
+ * will cause a compilation error. The method name will be used to determine
+ * what to call on the logger.
+ * <pre>
+ * log.name(exp)
+ * </pre>is mapped to
+ * <pre>
+ * if (log.isNameEnabled() {
+ *    log.name(exp)
+ * }</pre>
+ * Here name is a place holder for info, debug, warning, error, etc.
+ * If the expression exp is a constant or only a variable access the method call will
+ * not be transformed. But this will still cause a call on the injected logger.
+ *
+ * @since 2.2.0
+ */
+@java.lang.annotation.Documented
+@Retention(RetentionPolicy.SOURCE)
+@Target({ElementType.TYPE})
+@GroovyASTTransformationClass("org.codehaus.groovy.transform.LogASTTransformation")
+public @interface Log4j2 {
+    String value() default "log";
+    String category() default LogASTTransformation.DEFAULT_CATEGORY_NAME;
+    Class<? extends LogASTTransformation.LoggingStrategy> loggingStrategy() default Log4j2LoggingStrategy.class;
+
+    public static class Log4j2LoggingStrategy extends LogASTTransformation.AbstractLoggingStrategy {
+        private static final String LOGGER_NAME = "org.apache.logging.log4j.core.Logger";
+        private static final String LOG_MANAGER_NAME = "org.apache.logging.log4j.LogManager";
+
+        protected Log4j2LoggingStrategy(final GroovyClassLoader loader) {
+            super(loader);
+        }
+
+        public FieldNode addLoggerFieldToClass(ClassNode classNode, String logFieldName, String categoryName) {
+            return classNode.addField(logFieldName,
+                    Opcodes.ACC_FINAL | Opcodes.ACC_TRANSIENT | Opcodes.ACC_STATIC | Opcodes.ACC_PRIVATE,
+                    classNode(LOGGER_NAME),
+                    new MethodCallExpression(
+                            new ClassExpression(classNode(LOG_MANAGER_NAME)),
+                            "getLogger",
+                            new ConstantExpression(getCategoryName(classNode, categoryName))));
+        }
+
+        public boolean isLoggingMethod(String methodName) {
+            return methodName.matches("fatal|error|warn|info|debug|trace");
+        }
+
+        public Expression wrapLoggingMethodCall(Expression logVariable, String methodName, Expression originalExpression) {
+            MethodCallExpression condition = new MethodCallExpression(
+                    logVariable,
+                    "is" + methodName.substring(0, 1).toUpperCase(Locale.ENGLISH) + methodName.substring(1, methodName.length()) + "Enabled",
+                    ArgumentListExpression.EMPTY_ARGUMENTS);
+            condition.setImplicitThis(false);
+
+            return new TernaryExpression(
+                    new BooleanExpression(condition),
+                    originalExpression,
+                    ConstantExpression.NULL);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/util/logging/Slf4j.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/logging/Slf4j.java b/src/main/groovy/groovy/util/logging/Slf4j.java
new file mode 100644
index 0000000..0e866e4
--- /dev/null
+++ b/src/main/groovy/groovy/util/logging/Slf4j.java
@@ -0,0 +1,108 @@
+/*
+ *  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.logging;
+
+import groovy.lang.GroovyClassLoader;
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.FieldNode;
+import org.codehaus.groovy.ast.expr.ArgumentListExpression;
+import org.codehaus.groovy.ast.expr.BooleanExpression;
+import org.codehaus.groovy.ast.expr.ClassExpression;
+import org.codehaus.groovy.ast.expr.ConstantExpression;
+import org.codehaus.groovy.ast.expr.Expression;
+import org.codehaus.groovy.ast.expr.MethodCallExpression;
+import org.codehaus.groovy.ast.expr.TernaryExpression;
+import org.codehaus.groovy.transform.GroovyASTTransformationClass;
+import org.codehaus.groovy.transform.LogASTTransformation;
+import org.objectweb.asm.Opcodes;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.Locale;
+
+/**
+ * This local transform adds a logging ability to your program using
+ * LogBack logging. Every method call on a unbound variable named <i>log</i>
+ * will be mapped to a call to the logger. For this a <i>log</i> field will be
+ * inserted in the class. If the field already exists the usage of this transform
+ * will cause a compilation error. The method name will be used to determine
+ * what to call on the logger.
+ * <pre>
+ * log.name(exp)
+ * </pre>is mapped to
+ * <pre>
+ * if (log.isNameLoggable() {
+ *    log.name(exp)
+ * }</pre>
+ * Here name is a place holder for info, debug, warning, error, etc.
+ * If the expression exp is a constant or only a variable access the method call will
+ * not be transformed. But this will still cause a call on the injected logger.
+ *
+ * @author Hamlet D'Arcy
+ * @author Alberto Mijares
+ * @since 1.8.0
+ */
+@java.lang.annotation.Documented
+@Retention(RetentionPolicy.SOURCE)
+@Target({ElementType.TYPE})
+@GroovyASTTransformationClass("org.codehaus.groovy.transform.LogASTTransformation")
+public @interface Slf4j {
+    String value() default "log";
+    String category() default LogASTTransformation.DEFAULT_CATEGORY_NAME;
+    Class<? extends LogASTTransformation.LoggingStrategy> loggingStrategy() default Slf4jLoggingStrategy.class;
+
+    public static class Slf4jLoggingStrategy extends LogASTTransformation.AbstractLoggingStrategy {
+        private static final String LOGGER_NAME = "org.slf4j.Logger";
+        private static final String FACTORY_NAME = "org.slf4j.LoggerFactory";
+
+        protected Slf4jLoggingStrategy(final GroovyClassLoader loader) {
+            super(loader);
+        }
+
+        public FieldNode addLoggerFieldToClass(ClassNode classNode, String logFieldName, String categoryName) {
+            return classNode.addField(logFieldName,
+                    Opcodes.ACC_FINAL | Opcodes.ACC_TRANSIENT | Opcodes.ACC_STATIC | Opcodes.ACC_PRIVATE,
+                    classNode(LOGGER_NAME),
+                    new MethodCallExpression(
+                            new ClassExpression(classNode(FACTORY_NAME)),
+                            "getLogger",
+                            new ConstantExpression(getCategoryName(classNode, categoryName))));
+        }
+
+        public boolean isLoggingMethod(String methodName) {
+            return methodName.matches("error|warn|info|debug|trace");
+        }
+
+        public Expression wrapLoggingMethodCall(Expression logVariable, String methodName, Expression originalExpression) {
+            MethodCallExpression condition = new MethodCallExpression(
+                    logVariable,
+                    "is" + methodName.substring(0, 1).toUpperCase(Locale.ENGLISH) + methodName.substring(1, methodName.length()) + "Enabled",
+                    ArgumentListExpression.EMPTY_ARGUMENTS);
+            condition.setImplicitThis(false);
+
+            return new TernaryExpression(
+                    new BooleanExpression(condition),
+                    originalExpression,
+                    ConstantExpression.NULL);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/util/package.html
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/util/package.html b/src/main/groovy/groovy/util/package.html
new file mode 100644
index 0000000..e7a2c5a
--- /dev/null
+++ b/src/main/groovy/groovy/util/package.html
@@ -0,0 +1,28 @@
+<!--
+
+     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>package groovy.util.*</title>
+  </head>
+  <body>
+    <p>Various Groovy utilities for working with nodes, builders, logging, JUnit test cases, text expressions, Ant tasks or JMX MBeans.</p>
+  </body>
+</html>

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/xml/QName.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/xml/QName.java b/src/main/groovy/groovy/xml/QName.java
new file mode 100644
index 0000000..06a733d
--- /dev/null
+++ b/src/main/groovy/groovy/xml/QName.java
@@ -0,0 +1,287 @@
+/*
+ *  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.xml;
+
+import java.io.Serializable;
+
+/**
+ * <code>QName</code> class represents the value of a qualified name
+ * as specified in <a href="http://www.w3.org/TR/xmlschema-2/#QName">XML
+ * Schema Part2: Datatypes specification</a>.
+ * <p>
+ * The value of a QName contains a <b>namespaceURI</b>, a <b>localPart</b> and a <b>prefix</b>.
+ * The localPart provides the local part of the qualified name. The
+ * namespaceURI is a URI reference identifying the namespace.
+ */
+public class QName implements Serializable {
+    private static final long serialVersionUID = -9029109610006696081L;
+
+    /** comment/shared empty string */
+    private static final String EMPTY_STRING = "";
+
+    /** Field namespaceURI */
+    private String namespaceURI;
+
+    /** Field localPart */
+    private String localPart;
+
+    /** Field prefix */
+    private String prefix;
+
+    /**
+     * Constructor for the QName.
+     *
+     * @param localPart Local part of the QName
+     */
+    public QName(String localPart) {
+        this(EMPTY_STRING, localPart, EMPTY_STRING);
+    }
+
+    /**
+     * Constructor for the QName.
+     *
+     * @param namespaceURI Namespace URI for the QName
+     * @param localPart Local part of the QName.
+     */
+    public QName(String namespaceURI, String localPart) {
+        this(namespaceURI, localPart, EMPTY_STRING);
+    }
+
+    /**
+     * Constructor for the QName.
+     *
+     * @param namespaceURI Namespace URI for the QName
+     * @param localPart Local part of the QName.
+     * @param prefix Prefix of the QName.
+     */
+    public QName(String namespaceURI, String localPart, String prefix) {
+        this.namespaceURI = (namespaceURI == null)
+                ? EMPTY_STRING
+                : namespaceURI;
+        if (localPart == null) {
+            throw new IllegalArgumentException("invalid QName local part");
+        } else {
+            this.localPart = localPart;
+        }
+
+        if (prefix == null) {
+            throw new IllegalArgumentException("invalid QName prefix");
+        } else {
+            this.prefix = prefix;
+        }
+    }
+
+    /**
+     * Gets the Namespace URI for this QName
+     *
+     * @return Namespace URI
+     */
+    public String getNamespaceURI() {
+        return namespaceURI;
+    }
+
+    /**
+     * Gets the Local part for this QName
+     *
+     * @return Local part
+     */
+    public String getLocalPart() {
+        return localPart;
+    }
+
+    /**
+     * Gets the Prefix for this QName
+     *
+     * @return Prefix
+     */
+    public String getPrefix() {
+        return prefix;
+    }
+
+    /**
+     * Returns the fully qualified name of this QName
+     *
+     * @return  a string representation of the QName
+     */
+    public String getQualifiedName() {
+        return ((prefix.equals(EMPTY_STRING))
+                ? localPart
+                : prefix + ':' + localPart);
+    }
+
+    /**
+     * Returns a string representation of this QName
+     *
+     * @return  a string representation of the QName
+     */
+    public String toString() {
+        return ((namespaceURI.equals(EMPTY_STRING))
+                ? localPart
+                : '{' + namespaceURI + '}' + localPart);
+    }
+
+    /**
+     * Tests this QName for equality with another object.
+     * <p>
+     * If the given object is not a QName or String equivalent or is null then this method
+     * returns <tt>false</tt>.
+     * <p>
+     * For two QNames to be considered equal requires that both
+     * localPart and namespaceURI must be equal. This method uses
+     * <code>String.equals</code> to check equality of localPart
+     * and namespaceURI. Any class that extends QName is required
+     * to satisfy this equality contract.
+     *
+     * If the supplied object is a String, then it is split in two on the last colon
+     * and the first half is compared against the prefix || namespaceURI
+     * and the second half is compared against the localPart
+     *
+     * i.e.&#160;assert new QName("namespace","localPart").equals("namespace:localPart")
+     *
+     * Intended Usage: for gpath accessors, e.g.&#160;root.'urn:mynamespace:node'
+     *
+     * Warning: this equivalence is not commutative,
+     * i.e.&#160;qname.equals(string) may be true/false  but string.equals(qname) is always false
+     *
+     * <p>
+     * This method satisfies the general contract of the <code>Object.equals</code> method.
+     *
+     * @param o the reference object with which to compare
+     *
+     * @return <code>true</code> if the given object is identical to this
+     *      QName: <code>false</code> otherwise.
+     */
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null) return false;
+        if (o instanceof QName) {
+            final QName qName = (QName) o;
+            if (!namespaceURI.equals(qName.namespaceURI)) return false;
+            return localPart.equals(qName.localPart);
+
+        } else if (o instanceof String) {
+            final String string = (String)o;
+            if (string.length() == 0) return false;
+            int lastColonIndex = string.lastIndexOf(":");
+            if (lastColonIndex < 0 || lastColonIndex == string.length() - 1) return false;
+            final String stringPrefix = string.substring(0,lastColonIndex);
+            final String stringLocalPart = string.substring(lastColonIndex + 1);
+            if (stringPrefix.equals(prefix) || stringPrefix.equals(namespaceURI)) {
+                return localPart.equals(stringLocalPart);
+            }
+            return false;
+        }
+        return false;
+    }
+
+    /**
+     * Tests if this QName matches another object.
+     * <p>
+     * If the given object is not a QName or String equivalent or is null then this method
+     * returns <tt>false</tt>.
+     * <p>
+     * For two QNames to be considered matching requires that both
+     * localPart and namespaceURI must be equal or one of them is a wildcard.
+     *
+     * If the supplied object is a String, then it is split in two on the last colon
+     * and the first half is matched against the prefix || namespaceURI
+     * and the second half is matched against the localPart
+     *
+     * @param o the reference object with which to compare
+     *
+     * @return <code>true</code> if the given object matches
+     * this QName: <code>false</code> otherwise.
+     */
+    public boolean matches(Object o) {
+        if (this == o) return true;
+        if (o == null) return false;
+        if (o instanceof QName) {
+            final QName qName = (QName) o;
+            if (!namespaceURI.equals(qName.namespaceURI) && !namespaceURI.equals("*") && !qName.namespaceURI.equals("*")) return false;
+            return localPart.equals(qName.localPart) || localPart.equals("*") || qName.localPart.equals("*");
+        } else if (o instanceof String) {
+            final String string = (String)o;
+            if (string.length() == 0) return false;
+            // try matching against 'prefix:localname'
+            int lastColonIndex = string.lastIndexOf(":");
+            if (lastColonIndex < 0 && prefix.length() == 0) return string.equals(localPart);
+            if (lastColonIndex < 0 || lastColonIndex == string.length() - 1) return false;
+            final String stringPrefix = string.substring(0,lastColonIndex);
+            final String stringLocalPart = string.substring(lastColonIndex + 1);
+            if (stringPrefix.equals(prefix) || stringPrefix.equals(namespaceURI) || stringPrefix.equals("*")) {
+                return localPart.equals(stringLocalPart) || stringLocalPart.equals("*");
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns a QName holding the value of the specified String.
+     * <p>
+     * The string must be in the form returned by the QName.toString()
+     * method, i.e. "{namespaceURI}localPart", with the "{namespaceURI}"
+     * part being optional.
+     * <p>
+     * This method doesn't do a full validation of the resulting QName.
+     * In particular, it doesn't check that the resulting namespace URI
+     * is a legal URI (per RFC 2396 and RFC 2732), nor that the resulting
+     * local part is a legal NCName per the XML Namespaces specification.
+     *
+     * @param s the string to be parsed
+     * @throws java.lang.IllegalArgumentException If the specified String cannot be parsed as a QName
+     * @return QName corresponding to the given String
+     */
+    public static QName valueOf(String s) {
+
+        if ((s == null) || s.equals("")) {
+            throw new IllegalArgumentException("invalid QName literal");
+        }
+
+        if (s.charAt(0) == '{') {
+            int i = s.indexOf('}');
+
+            if (i == -1) {
+                throw new IllegalArgumentException("invalid QName literal");
+            }
+
+            if (i == s.length() - 1) {
+                throw new IllegalArgumentException("invalid QName literal");
+            } else {
+                return new QName(s.substring(1, i), s.substring(i + 1));
+            }
+        } else {
+            return new QName(s);
+        }
+    }
+
+    /**
+     * Returns a hash code value for this QName object. The hash code
+     * is based on both the localPart and namespaceURI parts of the
+     * QName. This method satisfies the  general contract of the
+     * <code>Object.hashCode</code> method.
+     *
+     * @return a hash code value for this Qname object
+     */
+    public int hashCode() {
+        int result;
+        result = namespaceURI.hashCode();
+        result = 29 * result + localPart.hashCode();
+        return result;
+    }
+} 
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/inspect/Inspector.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/inspect/Inspector.java b/src/main/groovy/inspect/Inspector.java
deleted file mode 100644
index f0c94a7..0000000
--- a/src/main/groovy/inspect/Inspector.java
+++ /dev/null
@@ -1,348 +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.inspect;
-
-import groovy.lang.GroovyObject;
-import groovy.lang.MetaClass;
-import groovy.lang.MetaMethod;
-import groovy.lang.PropertyValue;
-import org.codehaus.groovy.reflection.CachedClass;
-import org.codehaus.groovy.runtime.DefaultGroovyMethods;
-import org.codehaus.groovy.runtime.InvokerHelper;
-
-import java.io.PrintStream;
-import java.io.Serializable;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * The Inspector provides a unified access to an object's
- * information that can be determined by introspection.
- *
- * @author Dierk Koenig
- */
-public class Inspector {
-    protected Object objectUnderInspection;
-
-    // Indexes to retrieve Class Property information
-    public static final int CLASS_PACKAGE_IDX = 0;
-    public static final int CLASS_CLASS_IDX = 1;
-    public static final int CLASS_INTERFACE_IDX = 2;
-    public static final int CLASS_SUPERCLASS_IDX = 3;
-    public static final int CLASS_OTHER_IDX = 4;
-
-    // Indexes to retrieve field and method information
-    public static final int MEMBER_ORIGIN_IDX = 0;
-    public static final int MEMBER_MODIFIER_IDX = 1;
-    public static final int MEMBER_DECLARER_IDX = 2;
-    public static final int MEMBER_TYPE_IDX = 3;
-    public static final int MEMBER_NAME_IDX = 4;
-    public static final int MEMBER_PARAMS_IDX = 5;
-    public static final int MEMBER_VALUE_IDX = 5;
-    public static final int MEMBER_EXCEPTIONS_IDX = 6;
-
-    public static final String NOT_APPLICABLE = "n/a";
-    public static final String GROOVY = "GROOVY";
-    public static final String JAVA = "JAVA";
-
-    /**
-     * @param objectUnderInspection must not be null
-     */
-    public Inspector(Object objectUnderInspection) {
-        if (null == objectUnderInspection) {
-            throw new IllegalArgumentException("argument must not be null");
-        }
-        this.objectUnderInspection = objectUnderInspection;
-    }
-
-    /**
-     * Get the Class Properties of the object under inspection.
-     *
-     * @return String array to be indexed by the CLASS_xxx_IDX constants
-     */
-    public String[] getClassProps() {
-        String[] result = new String[CLASS_OTHER_IDX + 1];
-        Package pack = getClassUnderInspection().getPackage();
-        result[CLASS_PACKAGE_IDX] = "package " + ((pack == null) ? NOT_APPLICABLE : pack.getName());
-        String modifiers = Modifier.toString(getClassUnderInspection().getModifiers());
-        result[CLASS_CLASS_IDX] = modifiers + " class " + shortName(getClassUnderInspection());
-        result[CLASS_INTERFACE_IDX] = "implements ";
-        Class[] interfaces = getClassUnderInspection().getInterfaces();
-        for (Class anInterface : interfaces) {
-            result[CLASS_INTERFACE_IDX] += shortName(anInterface) + " ";
-        }
-        result[CLASS_SUPERCLASS_IDX] = "extends " + shortName(getClassUnderInspection().getSuperclass());
-        result[CLASS_OTHER_IDX] = "is Primitive: " + getClassUnderInspection().isPrimitive()
-                + ", is Array: " + getClassUnderInspection().isArray()
-                + ", is Groovy: " + isGroovy();
-        return result;
-    }
-
-    public boolean isGroovy() {
-        return GroovyObject.class.isAssignableFrom(getClassUnderInspection());
-    }
-
-    /**
-     * Gets the object being inspected.
-     *
-     * @return the object
-     */
-    public Object getObject() {
-        return objectUnderInspection;
-    }
-
-    /**
-     * Get info about usual Java instance and class Methods as well as Constructors.
-     *
-     * @return Array of StringArrays that can be indexed with the MEMBER_xxx_IDX constants
-     */
-    public Object[] getMethods() {
-        Method[] methods = getClassUnderInspection().getMethods();
-        Constructor[] ctors = getClassUnderInspection().getConstructors();
-        Object[] result = new Object[methods.length + ctors.length];
-        int resultIndex = 0;
-        for (; resultIndex < methods.length; resultIndex++) {
-            Method method = methods[resultIndex];
-            result[resultIndex] = methodInfo(method);
-        }
-        for (int i = 0; i < ctors.length; i++, resultIndex++) {
-            Constructor ctor = ctors[i];
-            result[resultIndex] = methodInfo(ctor);
-        }
-        return result;
-    }
-
-    /**
-     * Get info about instance and class Methods that are dynamically added through Groovy.
-     *
-     * @return Array of StringArrays that can be indexed with the MEMBER_xxx_IDX constants
-     */
-    public Object[] getMetaMethods() {
-        MetaClass metaClass = InvokerHelper.getMetaClass(objectUnderInspection);
-        List metaMethods = metaClass.getMetaMethods();
-        Object[] result = new Object[metaMethods.size()];
-        int i = 0;
-        for (Iterator iter = metaMethods.iterator(); iter.hasNext(); i++) {
-            MetaMethod metaMethod = (MetaMethod) iter.next();
-            result[i] = methodInfo(metaMethod);
-        }
-        return result;
-    }
-
-    /**
-     * Get info about usual Java public fields incl. constants.
-     *
-     * @return Array of StringArrays that can be indexed with the MEMBER_xxx_IDX constants
-     */
-    public Object[] getPublicFields() {
-        Field[] fields = getClassUnderInspection().getFields();
-        Object[] result = new Object[fields.length];
-        for (int i = 0; i < fields.length; i++) {
-            Field field = fields[i];
-            result[i] = fieldInfo(field);
-        }
-        return result;
-    }
-
-    /**
-     * Get info about Properties (Java and Groovy alike).
-     *
-     * @return Array of StringArrays that can be indexed with the MEMBER_xxx_IDX constants
-     */
-    public Object[] getPropertyInfo() {
-        List props = DefaultGroovyMethods.getMetaPropertyValues(objectUnderInspection);
-        Object[] result = new Object[props.size()];
-        int i = 0;
-        for (Iterator iter = props.iterator(); iter.hasNext(); i++) {
-            PropertyValue pv = (PropertyValue) iter.next();
-            result[i] = fieldInfo(pv);
-        }
-        return result;
-    }
-
-    protected String[] fieldInfo(Field field) {
-        String[] result = new String[MEMBER_VALUE_IDX + 1];
-        result[MEMBER_ORIGIN_IDX] = JAVA;
-        result[MEMBER_MODIFIER_IDX] = Modifier.toString(field.getModifiers());
-        result[MEMBER_DECLARER_IDX] = shortName(field.getDeclaringClass());
-        result[MEMBER_TYPE_IDX] = shortName(field.getType());
-        result[MEMBER_NAME_IDX] = field.getName();
-        try {
-            result[MEMBER_VALUE_IDX] = InvokerHelper.inspect(field.get(objectUnderInspection));
-        } catch (IllegalAccessException e) {
-            result[MEMBER_VALUE_IDX] = NOT_APPLICABLE;
-        }
-        return withoutNulls(result);
-    }
-
-    protected String[] fieldInfo(PropertyValue pv) {
-        String[] result = new String[MEMBER_VALUE_IDX + 1];
-        result[MEMBER_ORIGIN_IDX] = GROOVY;
-        result[MEMBER_MODIFIER_IDX] = "public";
-        result[MEMBER_DECLARER_IDX] = NOT_APPLICABLE;
-        result[MEMBER_TYPE_IDX] = shortName(pv.getType());
-        result[MEMBER_NAME_IDX] = pv.getName();
-        try {
-            result[MEMBER_VALUE_IDX] = InvokerHelper.inspect(pv.getValue());
-        } catch (Exception e) {
-            result[MEMBER_VALUE_IDX] = NOT_APPLICABLE;
-        }
-        return withoutNulls(result);
-    }
-
-    protected Class getClassUnderInspection() {
-        return objectUnderInspection.getClass();
-    }
-
-    public static String shortName(Class clazz) {
-        if (null == clazz) return NOT_APPLICABLE;
-        String className = clazz.getName();
-        if (null == clazz.getPackage()) return className;
-        String packageName = clazz.getPackage().getName();
-        int offset = packageName.length();
-        if (offset > 0) offset++;
-        className = className.substring(offset);
-        return className;
-    }
-
-    protected String[] methodInfo(Method method) {
-        String[] result = new String[MEMBER_EXCEPTIONS_IDX + 1];
-        int mod = method.getModifiers();
-        result[MEMBER_ORIGIN_IDX] = JAVA;
-        result[MEMBER_DECLARER_IDX] = shortName(method.getDeclaringClass());
-        result[MEMBER_MODIFIER_IDX] = Modifier.toString(mod);
-        result[MEMBER_NAME_IDX] = method.getName();
-        result[MEMBER_TYPE_IDX] = shortName(method.getReturnType());
-        Class[] params = method.getParameterTypes();
-        StringBuilder sb = new StringBuilder();
-        for (int j = 0; j < params.length; j++) {
-            sb.append(shortName(params[j]));
-            if (j < (params.length - 1)) sb.append(", ");
-        }
-        result[MEMBER_PARAMS_IDX] = sb.toString();
-        sb.setLength(0);
-        Class[] exceptions = method.getExceptionTypes();
-        for (int k = 0; k < exceptions.length; k++) {
-            sb.append(shortName(exceptions[k]));
-            if (k < (exceptions.length - 1)) sb.append(", ");
-        }
-        result[MEMBER_EXCEPTIONS_IDX] = sb.toString();
-        return withoutNulls(result);
-    }
-
-    protected String[] methodInfo(Constructor ctor) {
-        String[] result = new String[MEMBER_EXCEPTIONS_IDX + 1];
-        int mod = ctor.getModifiers();
-        result[MEMBER_ORIGIN_IDX] = JAVA;
-        result[MEMBER_MODIFIER_IDX] = Modifier.toString(mod);
-        result[MEMBER_DECLARER_IDX] = shortName(ctor.getDeclaringClass());
-        result[MEMBER_TYPE_IDX] = shortName(ctor.getDeclaringClass());
-        result[MEMBER_NAME_IDX] = ctor.getName();
-        Class[] params = ctor.getParameterTypes();
-        StringBuilder sb = new StringBuilder();
-        for (int j = 0; j < params.length; j++) {
-            sb.append(shortName(params[j]));
-            if (j < (params.length - 1)) sb.append(", ");
-        }
-        result[MEMBER_PARAMS_IDX] = sb.toString();
-        sb.setLength(0);
-        Class[] exceptions = ctor.getExceptionTypes();
-        for (int k = 0; k < exceptions.length; k++) {
-            sb.append(shortName(exceptions[k]));
-            if (k < (exceptions.length - 1)) sb.append(", ");
-        }
-        result[MEMBER_EXCEPTIONS_IDX] = sb.toString();
-        return withoutNulls(result);
-    }
-
-    protected String[] methodInfo(MetaMethod method) {
-        String[] result = new String[MEMBER_EXCEPTIONS_IDX + 1];
-        int mod = method.getModifiers();
-        result[MEMBER_ORIGIN_IDX] = GROOVY;
-        result[MEMBER_MODIFIER_IDX] = Modifier.toString(mod);
-        result[MEMBER_DECLARER_IDX] = shortName(method.getDeclaringClass().getTheClass());
-        result[MEMBER_TYPE_IDX] = shortName(method.getReturnType());
-        result[MEMBER_NAME_IDX] = method.getName();
-        CachedClass[] params = method.getParameterTypes();
-        StringBuilder sb = new StringBuilder();
-        for (int j = 0; j < params.length; j++) {
-            sb.append(shortName(params[j].getTheClass()));
-            if (j < (params.length - 1)) sb.append(", ");
-        }
-        result[MEMBER_PARAMS_IDX] = sb.toString();
-        result[MEMBER_EXCEPTIONS_IDX] = NOT_APPLICABLE; // no exception info for Groovy MetaMethods
-        return withoutNulls(result);
-    }
-
-    protected String[] withoutNulls(String[] toNormalize) {
-        for (int i = 0; i < toNormalize.length; i++) {
-            String s = toNormalize[i];
-            if (null == s) toNormalize[i] = NOT_APPLICABLE;
-        }
-        return toNormalize;
-    }
-
-    public static void print(Object[] memberInfo) {
-        print(System.out, memberInfo);
-    }
-
-    static void print(final PrintStream out, Object[] memberInfo) {
-        for (int i = 0; i < memberInfo.length; i++) {
-            String[] metaMethod = (String[]) memberInfo[i];
-            out.print(i + ":\t");
-            for (String s : metaMethod) {
-                out.print(s + " ");
-            }
-            out.println("");
-        }
-    }
-
-    public static Collection sort(List<Object> memberInfo) {
-        Collections.sort(memberInfo, new MemberComparator());
-        return memberInfo;
-    }
-
-    public static class MemberComparator implements Comparator<Object>, Serializable {
-        private static final long serialVersionUID = -7691851726606749541L;
-
-        public int compare(Object a, Object b) {
-            String[] aStr = (String[]) a;
-            String[] bStr = (String[]) b;
-            int result = aStr[Inspector.MEMBER_NAME_IDX].compareTo(bStr[Inspector.MEMBER_NAME_IDX]);
-            if (0 != result) return result;
-            result = aStr[Inspector.MEMBER_TYPE_IDX].compareTo(bStr[Inspector.MEMBER_TYPE_IDX]);
-            if (0 != result) return result;
-            result = aStr[Inspector.MEMBER_PARAMS_IDX].compareTo(bStr[Inspector.MEMBER_PARAMS_IDX]);
-            if (0 != result) return result;
-            result = aStr[Inspector.MEMBER_DECLARER_IDX].compareTo(bStr[Inspector.MEMBER_DECLARER_IDX]);
-            if (0 != result) return result;
-            result = aStr[Inspector.MEMBER_MODIFIER_IDX].compareTo(bStr[Inspector.MEMBER_MODIFIER_IDX]);
-            if (0 != result) return result;
-            result = aStr[Inspector.MEMBER_ORIGIN_IDX].compareTo(bStr[Inspector.MEMBER_ORIGIN_IDX]);
-            return result;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/inspect/package.html
----------------------------------------------------------------------
diff --git a/src/main/groovy/inspect/package.html b/src/main/groovy/inspect/package.html
deleted file mode 100644
index 6d80c2b..0000000
--- a/src/main/groovy/inspect/package.html
+++ /dev/null
@@ -1,28 +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>package groovy.inspect.*</title>
-  </head>
-  <body>
-    <p>Classes for inspecting object properties through introspection.</p>
-  </body>
-</html>

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/io/EncodingAwareBufferedWriter.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/io/EncodingAwareBufferedWriter.java b/src/main/groovy/io/EncodingAwareBufferedWriter.java
deleted file mode 100644
index 2faaaeb..0000000
--- a/src/main/groovy/io/EncodingAwareBufferedWriter.java
+++ /dev/null
@@ -1,58 +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.io;
-
-import java.io.BufferedWriter;
-import java.io.OutputStreamWriter;
-import java.nio.charset.Charset;
-
-/**
- * A buffered writer only for OutputStreamWriter that is aware of
- * the encoding of the OutputStreamWriter.
- *
- * @author Paul King
- */
-
-public class EncodingAwareBufferedWriter extends BufferedWriter {
-    private final OutputStreamWriter out;
-    public EncodingAwareBufferedWriter(OutputStreamWriter out) {
-        super(out);
-        this.out = out;
-    }
-
-    /**
-     * The encoding as returned by the underlying OutputStreamWriter. Can be the historical name.
-     *
-     * @return the encoding
-     * @see java.io.OutputStreamWriter#getEncoding()
-     */
-    public String getEncoding() {
-        return out.getEncoding();
-    }
-
-    /**
-     * The encoding as returned by the underlying OutputStreamWriter. Will be the preferred name.
-     *
-     * @return the encoding
-     * @see java.io.OutputStreamWriter#getEncoding()
-     */
-    public String getNormalizedEncoding() {
-        return Charset.forName(getEncoding()).name();
-    }
-}

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/io/FileType.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/io/FileType.java b/src/main/groovy/io/FileType.java
deleted file mode 100644
index 18727e4..0000000
--- a/src/main/groovy/io/FileType.java
+++ /dev/null
@@ -1,31 +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.io;
-
-/**
- * Represents particular files of interest.
- */
-public enum FileType {
-    /** Represents normal files */
-    FILES,
-    /** Represents directories */
-    DIRECTORIES,
-    /** Represents both normal files and directories */
-    ANY
-}