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:13 UTC

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

http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/lang/MetaClassImpl.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/lang/MetaClassImpl.java b/src/main/groovy/lang/MetaClassImpl.java
deleted file mode 100644
index c453a3f..0000000
--- a/src/main/groovy/lang/MetaClassImpl.java
+++ /dev/null
@@ -1,4021 +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.lang;
-
-import org.apache.groovy.internal.util.UncheckedThrow;
-import org.codehaus.groovy.GroovyBugError;
-import org.codehaus.groovy.ast.ClassNode;
-import org.codehaus.groovy.classgen.asm.BytecodeHelper;
-import org.codehaus.groovy.control.CompilationUnit;
-import org.codehaus.groovy.control.Phases;
-import org.codehaus.groovy.reflection.CacheAccessControlException;
-import org.codehaus.groovy.reflection.CachedClass;
-import org.codehaus.groovy.reflection.CachedConstructor;
-import org.codehaus.groovy.reflection.CachedField;
-import org.codehaus.groovy.reflection.CachedMethod;
-import org.codehaus.groovy.reflection.ClassInfo;
-import org.codehaus.groovy.reflection.GeneratedMetaMethod;
-import org.codehaus.groovy.reflection.ParameterTypes;
-import org.codehaus.groovy.reflection.ReflectionCache;
-import org.codehaus.groovy.reflection.android.AndroidSupport;
-import org.codehaus.groovy.runtime.ArrayTypeUtils;
-import org.codehaus.groovy.runtime.ConvertedClosure;
-import org.codehaus.groovy.runtime.CurriedClosure;
-import org.codehaus.groovy.runtime.DefaultGroovyMethods;
-import org.codehaus.groovy.runtime.GeneratedClosure;
-import org.codehaus.groovy.runtime.GroovyCategorySupport;
-import org.codehaus.groovy.runtime.InvokerHelper;
-import org.codehaus.groovy.runtime.InvokerInvocationException;
-import org.codehaus.groovy.runtime.MetaClassHelper;
-import org.codehaus.groovy.runtime.MethodClosure;
-import org.codehaus.groovy.runtime.callsite.AbstractCallSite;
-import org.codehaus.groovy.runtime.callsite.CallSite;
-import org.codehaus.groovy.runtime.callsite.ConstructorSite;
-import org.codehaus.groovy.runtime.callsite.MetaClassConstructorSite;
-import org.codehaus.groovy.runtime.callsite.PogoMetaClassSite;
-import org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite;
-import org.codehaus.groovy.runtime.callsite.PojoMetaClassSite;
-import org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite;
-import org.codehaus.groovy.runtime.callsite.StaticMetaClassSite;
-import org.codehaus.groovy.runtime.callsite.StaticMetaMethodSite;
-import org.codehaus.groovy.runtime.metaclass.ClosureMetaMethod;
-import org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl;
-import org.codehaus.groovy.runtime.metaclass.MetaMethodIndex;
-import org.codehaus.groovy.runtime.metaclass.MethodMetaProperty.GetBeanMethodMetaProperty;
-import org.codehaus.groovy.runtime.metaclass.MethodMetaProperty.GetMethodMetaProperty;
-import org.codehaus.groovy.runtime.metaclass.MethodSelectionException;
-import org.codehaus.groovy.runtime.metaclass.MissingMethodExceptionNoStack;
-import org.codehaus.groovy.runtime.metaclass.MissingMethodExecutionFailed;
-import org.codehaus.groovy.runtime.metaclass.MissingPropertyExceptionNoStack;
-import org.codehaus.groovy.runtime.metaclass.MixinInstanceMetaMethod;
-import org.codehaus.groovy.runtime.metaclass.MultipleSetterProperty;
-import org.codehaus.groovy.runtime.metaclass.NewInstanceMetaMethod;
-import org.codehaus.groovy.runtime.metaclass.NewMetaMethod;
-import org.codehaus.groovy.runtime.metaclass.NewStaticMetaMethod;
-import org.codehaus.groovy.runtime.metaclass.TransformMetaMethod;
-import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation;
-import org.codehaus.groovy.runtime.typehandling.NumberMathModificationInfo;
-import org.codehaus.groovy.runtime.wrappers.Wrapper;
-import org.codehaus.groovy.util.ComplexKeyHashMap;
-import org.codehaus.groovy.util.FastArray;
-import org.codehaus.groovy.util.SingleKeyHashMap;
-import org.objectweb.asm.ClassVisitor;
-
-import java.beans.BeanInfo;
-import java.beans.EventSetDescriptor;
-import java.beans.IntrospectionException;
-import java.beans.Introspector;
-import java.beans.PropertyDescriptor;
-import java.lang.reflect.Array;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.lang.reflect.Proxy;
-import java.net.URL;
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-import static org.codehaus.groovy.ast.tools.GeneralUtils.inSamePackage;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.isDefaultVisibility;
-import static org.codehaus.groovy.reflection.ReflectionCache.isAssignableFrom;
-
-/**
- * Allows methods to be dynamically added to existing classes at runtime
- * @see groovy.lang.MetaClass
- */
-public class MetaClassImpl implements MetaClass, MutableMetaClass {
-
-    public static final Object[] EMPTY_ARGUMENTS = {};
-
-    protected static final String STATIC_METHOD_MISSING = "$static_methodMissing";
-    protected static final String STATIC_PROPERTY_MISSING = "$static_propertyMissing";
-    protected static final String METHOD_MISSING = "methodMissing";
-    protected static final String PROPERTY_MISSING = "propertyMissing";
-    protected static final String INVOKE_METHOD_METHOD = "invokeMethod";
-
-    private static final String CLOSURE_CALL_METHOD = "call";
-    private static final String CLOSURE_DO_CALL_METHOD = "doCall";
-    private static final String GET_PROPERTY_METHOD = "getProperty";
-    private static final String SET_PROPERTY_METHOD = "setProperty";
-    private static final Class[] METHOD_MISSING_ARGS = new Class[]{String.class, Object.class};
-    private static final Class[] GETTER_MISSING_ARGS = new Class[]{String.class};
-    private static final Class[] SETTER_MISSING_ARGS = METHOD_MISSING_ARGS;
-    private static final Comparator<CachedClass> CACHED_CLASS_NAME_COMPARATOR = new Comparator<CachedClass>() {
-        public int compare(final CachedClass o1, final CachedClass o2) {
-            return o1.getName().compareTo(o2.getName());
-        }
-    };
-    private static final MetaMethod[] EMPTY = new MetaMethod[0];
-    private static final MetaMethod AMBIGUOUS_LISTENER_METHOD = new DummyMetaMethod();
-
-    protected final Class theClass;
-    protected final CachedClass theCachedClass;
-    protected final boolean isGroovyObject;
-    protected final boolean isMap;
-    protected final MetaMethodIndex metaMethodIndex;
-
-    private final Index classPropertyIndex = new MethodIndex();
-    private final SingleKeyHashMap staticPropertyIndex = new SingleKeyHashMap();
-    private final Map<String, MetaMethod> listeners = new HashMap<String, MetaMethod>();
-    private final List<MetaMethod> allMethods = new ArrayList<MetaMethod>();
-    // we only need one of these that can be reused over and over.
-    private final MetaProperty arrayLengthProperty = new MetaArrayLengthProperty();
-    private final Index classPropertyIndexForSuper = new MethodIndex();
-    private final Set<MetaMethod> newGroovyMethodsSet = new HashSet<MetaMethod>();
-    private final MetaMethod[] myNewMetaMethods;
-    private final MetaMethod[] additionalMetaMethods;
-
-    protected MetaMethod getPropertyMethod;
-    protected MetaMethod invokeMethodMethod;
-    protected MetaMethod setPropertyMethod;
-    protected MetaClassRegistry registry;
-    private ClassNode classNode;
-    private FastArray constructors;
-    private volatile boolean initialized;
-    private MetaMethod genericGetMethod;
-    private MetaMethod genericSetMethod;
-    private MetaMethod propertyMissingGet;
-    private MetaMethod propertyMissingSet;
-    private MetaMethod methodMissing;
-    private MetaMethodIndex.Header mainClassMethodHeader;
-
-     /**
-      * Constructor
-      *
-      * @param theClass The class this is the metaclass dor
-      * @param add The methods for this class
-      */
-    public MetaClassImpl(final Class theClass, MetaMethod[] add) {
-        this.theClass = theClass;
-        theCachedClass = ReflectionCache.getCachedClass(theClass);
-        this.isGroovyObject = GroovyObject.class.isAssignableFrom(theClass);
-        this.isMap = Map.class.isAssignableFrom(theClass);
-        this.registry = GroovySystem.getMetaClassRegistry();
-        metaMethodIndex = new MetaMethodIndex(theCachedClass);
-        final MetaMethod[] metaMethods = theCachedClass.getNewMetaMethods();
-        if (add != null && !(add.length == 0)) {
-            List<MetaMethod> arr = new ArrayList<MetaMethod>();
-            arr.addAll(Arrays.asList(metaMethods));
-            arr.addAll(Arrays.asList(add));
-            myNewMetaMethods = arr.toArray(new MetaMethod[arr.size()]);
-            additionalMetaMethods = metaMethods;
-        }
-        else {
-            myNewMetaMethods = metaMethods;
-            additionalMetaMethods = EMPTY;
-        }
-    }
-
-    /**
-      * Constructor that sets the methods to null
-      *
-      * @param theClass The class this is the metaclass dor
-      */
-    public MetaClassImpl(final Class theClass) {
-        this(theClass, null);
-    }
-
-    /**
-     * Constructor with registry
-     *
-     * @param registry The metaclass registry for this MetaClass
-     * @param theClass The class
-     * @param add The methods
-     */
-    public MetaClassImpl(MetaClassRegistry registry, final Class theClass, MetaMethod add []) {
-        this(theClass, add);
-        this.registry = registry;
-        this.constructors = new FastArray(theCachedClass.getConstructors());
-    }
-
-    /**
-     * Constructor with registry setting methods to null
-     *
-     * @param registry The metaclass registry for this MetaClass
-     * @param theClass The class
-     */
-    public MetaClassImpl(MetaClassRegistry registry, final Class theClass) {
-        this(registry, theClass, null);
-    }
-
-    /**
-     * Returns the cached class for this metaclass
-     *
-     * @return The cached class.
-     */
-    public final CachedClass getTheCachedClass() {
-        return theCachedClass;
-    }
-
-    /**
-     * Returns the registry for this metaclass
-     *
-     * @return The resgistry
-     */
-    public MetaClassRegistry getRegistry() {
-        return registry;
-    }
-
-    /**
-     * @see MetaObjectProtocol#respondsTo(Object, String, Object[])
-     */
-    public List respondsTo(Object obj, String name, Object[] argTypes) {
-        Class[] classes = MetaClassHelper.castArgumentsToClassArray(argTypes);
-        MetaMethod m = getMetaMethod(name, classes);
-        if (m!=null) {
-            return Collections.singletonList(m);
-        }
-        return Collections.emptyList();
-    }
-
-    /**
-     * @see MetaObjectProtocol#respondsTo(Object, String)
-     */
-    public List respondsTo(final Object obj, final String name) {
-        final Object o = getMethods(getTheClass(), name, false);
-        if (o instanceof FastArray)
-            return ((FastArray) o).toList();
-        else
-            return Collections.singletonList(o);
-    }
-
-    /**
-     * @see MetaObjectProtocol#hasProperty(Object,String)
-     */
-    public MetaProperty hasProperty(Object obj, String name) {
-        return getMetaProperty(name);
-    }
-
-    /**
-     * @see MetaObjectProtocol#getMetaProperty(String)
-     */
-    public MetaProperty getMetaProperty(String name) {
-        SingleKeyHashMap propertyMap = classPropertyIndex.getNotNull(theCachedClass);
-        if (propertyMap.containsKey(name)) {
-            return (MetaProperty) propertyMap.get(name);
-        } else if (staticPropertyIndex.containsKey(name)) {
-            return (MetaProperty) staticPropertyIndex.get(name);
-        } else {
-            propertyMap = classPropertyIndexForSuper.getNotNull(theCachedClass);
-            if (propertyMap.containsKey(name))
-                return (MetaProperty) propertyMap.get(name);
-            else {
-                CachedClass superClass = theCachedClass;
-                while (superClass != null && superClass != ReflectionCache.OBJECT_CLASS) {
-                    final MetaBeanProperty property = findPropertyInClassHierarchy(name, superClass);
-                    if (property != null) {
-                        onSuperPropertyFoundInHierarchy(property);
-                        return property;
-                    }
-                    superClass = superClass.getCachedSuperClass();
-                }
-                return null;
-            }
-        }
-    }
-
-    /**
-     * @see MetaObjectProtocol#getStaticMetaMethod(String, Object[])
-     */
-    public MetaMethod getStaticMetaMethod(String name, Object[] argTypes) {
-        Class[] classes = MetaClassHelper.castArgumentsToClassArray(argTypes);
-        return pickStaticMethod(name, classes);
-    }
-
-
-    /**
-     * @see MetaObjectProtocol#getMetaMethod(String, Object[])
-     */
-    public MetaMethod getMetaMethod(String name, Object[] argTypes) {
-        Class[] classes = MetaClassHelper.castArgumentsToClassArray(argTypes);
-        return pickMethod(name, classes);
-    }
-
-    /**
-     *Returns the class this object this is the metaclass of.
-     *
-     * @return The class contained by this metaclass
-     */
-    public Class getTheClass() {
-        return this.theClass;
-    }
-
-    /**
-     * Return wether the class represented by this metaclass instance is an instance of the GroovyObject class
-     *
-     * @return true if this is a groovy class, false otherwise.
-     */
-    public boolean isGroovyObject() {
-        return isGroovyObject;
-    }
-
-    /**
-     * Fills the method index
-     */
-    private void fillMethodIndex() {
-        mainClassMethodHeader = metaMethodIndex.getHeader(theClass);
-        LinkedList<CachedClass> superClasses = getSuperClasses();
-        CachedClass firstGroovySuper = calcFirstGroovySuperClass(superClasses);
-
-        Set<CachedClass> interfaces = theCachedClass.getInterfaces();
-        addInterfaceMethods(interfaces);
-
-        populateMethods(superClasses, firstGroovySuper);
-
-        inheritInterfaceNewMetaMethods(interfaces);
-        if (isGroovyObject) {
-          metaMethodIndex.copyMethodsToSuper();
-
-          connectMultimethods(superClasses, firstGroovySuper);
-          removeMultimethodsOverloadedWithPrivateMethods();
-
-          replaceWithMOPCalls(theCachedClass.mopMethods);
-        }
-    }
-
-    private void populateMethods(LinkedList<CachedClass> superClasses, CachedClass firstGroovySuper) {
-
-        MetaMethodIndex.Header header = metaMethodIndex.getHeader(firstGroovySuper.getTheClass());
-        CachedClass c;
-        Iterator<CachedClass> iter = superClasses.iterator();
-        for (; iter.hasNext();) {
-            c = iter.next();
-
-            CachedMethod[] cachedMethods = c.getMethods();
-            for (CachedMethod metaMethod : cachedMethods) {
-                addToAllMethodsIfPublic(metaMethod);
-                if (!metaMethod.isPrivate() || c == firstGroovySuper)
-                    addMetaMethodToIndex(metaMethod, header);
-            }
-
-            MetaMethod[] cachedMethods1 = getNewMetaMethods(c);
-            for (final MetaMethod method : cachedMethods1) {
-                if (!newGroovyMethodsSet.contains(method)) {
-                    newGroovyMethodsSet.add(method);
-                    addMetaMethodToIndex(method, header);
-                }
-            }
-
-            if (c == firstGroovySuper)
-              break;
-        }
-
-        MetaMethodIndex.Header last = header;
-        for (;iter.hasNext();) {
-            c = iter.next();
-            header = metaMethodIndex.getHeader(c.getTheClass());
-
-            if (last != null) {
-                metaMethodIndex.copyNonPrivateMethods(last, header);
-            }
-            last = header;
-
-            for (CachedMethod metaMethod : c.getMethods()) {
-                addToAllMethodsIfPublic(metaMethod);
-                addMetaMethodToIndex(metaMethod, header);
-            }
-
-            for (final MetaMethod method : getNewMetaMethods(c)) {
-                if (method.getName().equals("<init>") && !method.getDeclaringClass().equals(theCachedClass)) continue;
-                if (!newGroovyMethodsSet.contains(method)) {
-                    newGroovyMethodsSet.add(method);
-                    addMetaMethodToIndex(method, header);
-                }
-            }
-        }
-    }
-
-    private MetaMethod[] getNewMetaMethods(CachedClass c) {
-        if (theCachedClass != c)
-          return c.getNewMetaMethods();
-
-        return myNewMetaMethods;
-    }
-
-    private void addInterfaceMethods(Set<CachedClass> interfaces) {
-        MetaMethodIndex.Header header = metaMethodIndex.getHeader(theClass);
-        for (CachedClass c : interfaces) {
-            final CachedMethod[] m = c.getMethods();
-            for (int i = 0; i != m.length; ++i) {
-                MetaMethod method = m[i];
-                addMetaMethodToIndex(method, header);
-            }
-        }
-    }
-
-    protected LinkedList<CachedClass> getSuperClasses() {
-        LinkedList<CachedClass> superClasses = new LinkedList<CachedClass>();
-
-        if (theClass.isInterface()) {
-            superClasses.addFirst(ReflectionCache.OBJECT_CLASS);
-        } else {
-            for (CachedClass c = theCachedClass; c != null; c = c.getCachedSuperClass()) {
-                superClasses.addFirst(c);
-            }
-            if (theCachedClass.isArray && theClass != Object[].class && !theClass.getComponentType().isPrimitive()) {
-                superClasses.addFirst(ReflectionCache.OBJECT_ARRAY_CLASS);
-            }
-        }
-        return superClasses;
-    }
-
-    private void removeMultimethodsOverloadedWithPrivateMethods() {
-        MethodIndexAction mia = new MethodIndexAction() {
-            public boolean skipClass(Class clazz) {
-                return clazz == theClass;
-            }
-
-            public void methodNameAction(Class clazz, MetaMethodIndex.Entry e) {
-                if (e.methods == null)
-                  return;
-
-                boolean hasPrivate = false;
-                if (e.methods instanceof FastArray) {
-                    FastArray methods = (FastArray) e.methods;
-                    final int len = methods.size();
-                    final Object[] data = methods.getArray();
-                    for (int i = 0; i != len; ++i) {
-                        MetaMethod method = (MetaMethod) data[i];
-                        if (method.isPrivate() && clazz == method.getDeclaringClass().getTheClass()) {
-                            hasPrivate = true;
-                            break;
-                        }
-                    }
-                }
-                else {
-                    MetaMethod method = (MetaMethod) e.methods;
-                    if (method.isPrivate() && clazz == method.getDeclaringClass().getTheClass()) {
-                       hasPrivate = true;
-                    }
-                }
-
-                if (!hasPrivate) return;
-
-                // We have private methods for that name, so remove the
-                // multimethods. That is the same as in our index for
-                // super, so just copy the list from there. It is not
-                // possible to use a pointer here, because the methods
-                // in the index for super are replaced later by MOP
-                // methods like super$5$foo
-                final Object o = e.methodsForSuper;
-                if (o instanceof FastArray)
-                  e.methods = ((FastArray) o).copy();
-                else
-                  e.methods = o;
-            }
-        };
-        mia.iterate();
-    }
-
-
-    private void replaceWithMOPCalls(final CachedMethod[] mopMethods) {
-        // no MOP methods if not a child of GroovyObject
-        if (!isGroovyObject) return;
-
-        class MOPIter extends MethodIndexAction {
-            boolean useThis;
-
-            @Override
-            public void methodNameAction(Class clazz, MetaMethodIndex.Entry e) {
-                if (useThis) {
-                    if (e.methods == null)
-                      return;
-
-                    if (e.methods instanceof FastArray) {
-                        FastArray methods = (FastArray) e.methods;
-                        processFastArray(methods);
-                    }
-                    else {
-                        MetaMethod method = (MetaMethod) e.methods;
-                        if (method instanceof NewMetaMethod)
-                          return;
-                        if (useThis ^ Modifier.isPrivate(method.getModifiers())) return;
-                        String mopName = method.getMopName();
-                        int index = Arrays.binarySearch(mopMethods, mopName, CachedClass.CachedMethodComparatorWithString.INSTANCE);
-                        if (index >= 0) {
-                            int from = index;
-                            while (from > 0 && mopMethods[from-1].getName().equals(mopName))
-                              from--;
-                            int to = index;
-                            while (to < mopMethods.length-1 && mopMethods[to+1].getName().equals(mopName))
-                              to++;
-
-                            int matchingMethod = findMatchingMethod(mopMethods, from, to, method);
-                            if (matchingMethod != -1) {
-                                e.methods = mopMethods[matchingMethod];
-                            }
-                        }
-                    }
-                }
-                else {
-                    if (e.methodsForSuper == null)
-                      return;
-
-                    if (e.methodsForSuper instanceof FastArray) {
-                        FastArray methods = (FastArray) e.methodsForSuper;
-                        processFastArray(methods);
-                    }
-                    else {
-                        MetaMethod method = (MetaMethod) e.methodsForSuper;
-                        if (method instanceof NewMetaMethod)
-                          return;
-                        if (useThis ^ Modifier.isPrivate(method.getModifiers())) return;
-                        String mopName = method.getMopName();
-                        // GROOVY-4922: Due to a numbering scheme change, we must find the super$X$method which exists
-                        // with the highest number. If we don't, no method may be found, leading to a stack overflow
-                        String[] decomposedMopName = decomposeMopName(mopName);
-                        int distance = Integer.parseInt(decomposedMopName[1]);
-                        while (distance>0) {
-                            String fixedMopName = decomposedMopName[0] + distance + decomposedMopName[2];
-                            int index = Arrays.binarySearch(mopMethods, fixedMopName, CachedClass.CachedMethodComparatorWithString.INSTANCE);
-                            if (index >= 0) {
-                                int from = index;
-                                while (from > 0 && mopMethods[from-1].getName().equals(fixedMopName))
-                                  from--;
-                                int to = index;
-                                while (to < mopMethods.length-1 && mopMethods[to+1].getName().equals(fixedMopName))
-                                  to++;
-
-                                int matchingMethod = findMatchingMethod(mopMethods, from, to, method);
-                                if (matchingMethod != -1) {
-                                    e.methodsForSuper = mopMethods[matchingMethod];
-                                    distance = 0;
-                                }
-                            }
-                            distance--;
-                        }
-                    }
-                }
-            }
-
-            private String[] decomposeMopName(final String mopName) {
-                int idx = mopName.indexOf("$");
-                if (idx>0) {
-                    int eidx = mopName.indexOf("$", idx+1);
-                    if (eidx>0) {
-                        return new String[] {
-                                mopName.substring(0, idx+1),
-                                mopName.substring(idx+1, eidx),
-                                mopName.substring(eidx)
-                        };
-                    }
-                }
-                return new String[]{"","0",mopName};
-            }
-
-            private void processFastArray(FastArray methods) {
-                final int len = methods.size();
-                final Object[] data = methods.getArray();
-                for (int i = 0; i != len; ++i) {
-                    MetaMethod method = (MetaMethod) data[i];
-                    if (method instanceof NewMetaMethod) continue;
-                    boolean isPrivate = Modifier.isPrivate(method.getModifiers());
-                    if (useThis ^ isPrivate) continue;
-                    String mopName = method.getMopName();
-                    int index = Arrays.binarySearch(mopMethods, mopName, CachedClass.CachedMethodComparatorWithString.INSTANCE);
-                    if (index >= 0) {
-                        int from = index;
-                        while (from > 0 && mopMethods[from-1].getName().equals(mopName))
-                          from--;
-                        int to = index;
-                        while (to < mopMethods.length-1 && mopMethods[to+1].getName().equals(mopName))
-                          to++;
-
-                        int matchingMethod = findMatchingMethod(mopMethods, from, to, method);
-                        if (matchingMethod != -1) {
-                            methods.set(i, mopMethods[matchingMethod]);
-                        }
-                    }
-                }
-            }
-        }
-        MOPIter iter = new MOPIter();
-
-        // replace all calls for super with the correct MOP method
-        iter.useThis = false;
-        iter.iterate();
-        // replace all calls for this with the correct MOP method
-        iter.useThis = true;
-        iter.iterate();
-    }
-
-    private void inheritInterfaceNewMetaMethods(Set<CachedClass> interfaces) {
-        // add methods declared by DGM for interfaces
-        for (CachedClass cls : interfaces) {
-            MetaMethod methods[] = getNewMetaMethods(cls);
-            for (MetaMethod method : methods) {
-                boolean skip = false;
-                // skip DGM methods on an interface if the class already has the method
-                // but don't skip for GroovyObject-related methods as it breaks things :-(
-                if (method instanceof GeneratedMetaMethod && !isAssignableFrom(GroovyObject.class, method.getDeclaringClass().getTheClass())) {
-                    for (Method m : theClass.getMethods()) {
-                        if (method.getName().equals(m.getName())
-                                // below not true for DGM#push and also co-variant return scenarios
-                                //&& method.getReturnType().equals(m.getReturnType())
-                                && MetaMethod.equal(method.getParameterTypes(), m.getParameterTypes())) {
-                            skip = true;
-                            break;
-                        }
-                    }
-                }
-                if (!skip) {
-                    if (!newGroovyMethodsSet.contains(method)) {
-                        newGroovyMethodsSet.add(method);
-                    }
-                    addMetaMethodToIndex(method, mainClassMethodHeader);
-                }
-            }
-        }
-    }
-
-    private void connectMultimethods(List<CachedClass> superClasses, CachedClass firstGroovyClass) {
-        superClasses = DefaultGroovyMethods.reverse(superClasses);
-        MetaMethodIndex.Header last = null;
-        for (final CachedClass c : superClasses) {
-            MetaMethodIndex.Header methodIndex = metaMethodIndex.getHeader(c.getTheClass());
-            // We don't copy DGM methods to superclasses' indexes
-            // The reason we can do that is particular set of DGM methods in use,
-            // if at some point we will define DGM method for some Groovy class or
-            // for a class derived from such, we will need to revise this condition.
-            // It saves us a lot of space and some noticeable time
-            if (last != null) metaMethodIndex.copyNonPrivateNonNewMetaMethods(last, methodIndex);
-            last = methodIndex;
-
-            if (c == firstGroovyClass)
-                break;
-        }
-    }
-
-    private CachedClass calcFirstGroovySuperClass(Collection superClasses) {
-        if (theCachedClass.isInterface)
-          return ReflectionCache.OBJECT_CLASS;
-
-        CachedClass firstGroovy = null;
-        Iterator iter = superClasses.iterator();
-        for (; iter.hasNext();) {
-            CachedClass c = (CachedClass) iter.next();
-            if (GroovyObject.class.isAssignableFrom(c.getTheClass())) {
-              firstGroovy = c;
-              break;
-            }
-        }
-
-        if (firstGroovy == null)
-          firstGroovy = theCachedClass;
-        else {
-            if (firstGroovy.getTheClass() == GroovyObjectSupport.class && iter.hasNext()) {
-                firstGroovy = (CachedClass) iter.next();
-                if (firstGroovy.getTheClass() == Closure.class && iter.hasNext()) {
-                    firstGroovy = (CachedClass) iter.next();
-                }
-            }
-        }
-
-        return GroovyObject.class.isAssignableFrom(firstGroovy.getTheClass()) ? firstGroovy.getCachedSuperClass() : firstGroovy;
-    }
-
-    /**
-     * Gets all instance methods available on this class for the given name
-     *
-     * @return all the normal instance methods available on this class for the
-     *         given name
-     */
-    private Object getMethods(Class sender, String name, boolean isCallToSuper) {
-        Object answer;
-
-        final MetaMethodIndex.Entry entry = metaMethodIndex.getMethods(sender, name);
-        if (entry == null)
-            answer = FastArray.EMPTY_LIST;
-        else
-            if (isCallToSuper) {
-                answer = entry.methodsForSuper;
-            } else {
-                answer = entry.methods;
-            }
-
-        if (answer == null) answer = FastArray.EMPTY_LIST;
-
-        if (!isCallToSuper) {
-            List used = GroovyCategorySupport.getCategoryMethods(name);
-            if (used != null) {
-                FastArray arr;
-                if (answer instanceof MetaMethod) {
-                    arr = new FastArray();
-                    arr.add(answer);
-                }
-                else
-                    arr = ((FastArray) answer).copy();
-
-                for (Iterator iter = used.iterator(); iter.hasNext();) {
-                    MetaMethod element = (MetaMethod) iter.next();
-                    if (!element.getDeclaringClass().getTheClass().isAssignableFrom(sender))
-                      continue;
-                    filterMatchingMethodForCategory(arr, element);
-                }
-                answer = arr;
-            }
-        }
-        return answer;
-    }
-
-    /**
-     * Returns all the normal static methods on this class for the given name
-     *
-     * @return all the normal static methods available on this class for the
-     *         given name
-     */
-    private Object getStaticMethods(Class sender, String name) {
-        final MetaMethodIndex.Entry entry = metaMethodIndex.getMethods(sender, name);
-        if (entry == null)
-            return FastArray.EMPTY_LIST;
-        Object answer = entry.staticMethods;
-        if (answer == null)
-            return FastArray.EMPTY_LIST;
-        return answer;
-    }
-
-    /**
-     * Returns whether this MetaClassImpl has been modified. Since MetaClassImpl
-     * is not designed for modification this method always returns false
-     *
-     * @return false
-     */
-    public boolean isModified() {
-        return false;  // MetaClassImpl not designed for modification, just return false
-    }
-
-    /**
-     *Adds an instance method to this metaclass.
-     *
-     * @param method The method to be added
-     */
-    public void addNewInstanceMethod(Method method) {
-        final CachedMethod cachedMethod = CachedMethod.find(method);
-        NewInstanceMetaMethod newMethod = new NewInstanceMetaMethod(cachedMethod);
-        final CachedClass declaringClass = newMethod.getDeclaringClass();
-        addNewInstanceMethodToIndex(newMethod, metaMethodIndex.getHeader(declaringClass.getTheClass()));
-    }
-
-    private void addNewInstanceMethodToIndex(MetaMethod newMethod, MetaMethodIndex.Header header) {
-        if (!newGroovyMethodsSet.contains(newMethod)) {
-            newGroovyMethodsSet.add(newMethod);
-            addMetaMethodToIndex(newMethod, header);
-        }
-    }
-
-    /**
-     *Adds a static method to this metaclass.
-     *
-     * @param method The method to be added
-     */
-    public void addNewStaticMethod(Method method) {
-        final CachedMethod cachedMethod = CachedMethod.find(method);
-        NewStaticMetaMethod newMethod = new NewStaticMetaMethod(cachedMethod);
-        final CachedClass declaringClass = newMethod.getDeclaringClass();
-        addNewStaticMethodToIndex(newMethod, metaMethodIndex.getHeader(declaringClass.getTheClass()));
-    }
-
-    private void addNewStaticMethodToIndex(MetaMethod newMethod, MetaMethodIndex.Header header) {
-        if (!newGroovyMethodsSet.contains(newMethod)) {
-            newGroovyMethodsSet.add(newMethod);
-            addMetaMethodToIndex(newMethod, header);
-        }
-    }
-
-    /**
-     * Invoke a method on the given object with the given arguments.
-     *
-     * @param object The object the method should be invoked on.
-     * @param methodName The name of the method to invoke.
-     * @param arguments The arguments to the invoked method as null, a Tuple, an array or a single argument of any type.
-     *
-     * @return The result of the method invocation.
-     */
-    public Object invokeMethod(Object object, String methodName, Object arguments) {
-        if (arguments == null) {
-            return invokeMethod(object, methodName, MetaClassHelper.EMPTY_ARRAY);
-        }
-        if (arguments instanceof Tuple) {
-            Tuple tuple = (Tuple) arguments;
-            return invokeMethod(object, methodName, tuple.toArray());
-        }
-        if (arguments instanceof Object[]) {
-            return invokeMethod(object, methodName, (Object[]) arguments);
-        } else {
-            return invokeMethod(object, methodName, new Object[]{arguments});
-        }
-    }
-
-    /**
-     * Invoke a missing method on the given object with the given arguments.
-     *
-     * @param instance The object the method should be invoked on.
-     * @param methodName The name of the method to invoke.
-     * @param arguments The arguments to the invoked method.
-     *
-     * @return The result of the method invocation.
-     */
-    public Object invokeMissingMethod(Object instance, String methodName, Object[] arguments) {
-        return invokeMissingMethod(instance, methodName, arguments, null, false);
-    }
-
-    /**
-     * Invoke a missing property on the given object with the given arguments.
-     *
-     * @param instance The object the method should be invoked on.
-     * @param propertyName The name of the property to invoke.
-     * @param optionalValue The (optional) new value for the property
-     * @param isGetter Wether the method is a getter
-     *
-     * @return The result of the method invocation.
-     */
-    public Object invokeMissingProperty(Object instance, String propertyName, Object optionalValue, boolean isGetter) {
-        Class theClass = instance instanceof Class ? (Class)instance : instance.getClass();
-        CachedClass superClass = theCachedClass;
-        while(superClass != null && superClass != ReflectionCache.OBJECT_CLASS) {
-            final MetaBeanProperty property = findPropertyInClassHierarchy(propertyName, superClass);
-            if(property != null) {
-                onSuperPropertyFoundInHierarchy(property);
-                if(!isGetter) {
-                    property.setProperty(instance, optionalValue);
-                    return null;
-                }
-                else {
-                    return property.getProperty(instance);
-                }
-            }
-            superClass = superClass.getCachedSuperClass();
-        }
-        // got here to property not found, look for getProperty or setProperty overrides
-        if(isGetter) {
-            final Class[] getPropertyArgs = {String.class};
-            final MetaMethod method = findMethodInClassHierarchy(instance.getClass(), GET_PROPERTY_METHOD, getPropertyArgs, this);
-            if(method != null && method instanceof ClosureMetaMethod) {
-                onGetPropertyFoundInHierarchy(method);
-                return method.invoke(instance,new Object[]{propertyName});
-            }
-        }
-        else {
-            final Class[] setPropertyArgs = {String.class, Object.class};
-            final MetaMethod method = findMethodInClassHierarchy(instance.getClass(), SET_PROPERTY_METHOD, setPropertyArgs, this);
-            if(method != null && method instanceof ClosureMetaMethod) {
-                onSetPropertyFoundInHierarchy(method);
-                return method.invoke(instance, new Object[]{propertyName, optionalValue});
-            }
-        }
-
-        try {
-            if (!(instance instanceof Class)) {
-                if (isGetter) {
-                    if (propertyMissingGet != null) {
-                        return propertyMissingGet.invoke(instance, new Object[]{propertyName});
-                    }
-                } else {
-                    if (propertyMissingSet != null) {
-                        return propertyMissingSet.invoke(instance, new Object[]{propertyName, optionalValue});
-                    }
-                }
-            }
-        } catch (InvokerInvocationException iie) {
-            boolean shouldHandle = isGetter && propertyMissingGet != null;
-            if (!shouldHandle) shouldHandle = !isGetter && propertyMissingSet != null;
-            if (shouldHandle &&  iie.getCause() instanceof MissingPropertyException) {
-                throw (MissingPropertyException) iie.getCause();
-            }
-            throw iie;
-        }
-
-        if (instance instanceof Class && theClass != Class.class) {
-           final MetaProperty metaProperty = InvokerHelper.getMetaClass(Class.class).hasProperty(instance, propertyName);
-           if (metaProperty != null)
-             if (isGetter)
-               return metaProperty.getProperty(instance);
-             else {
-               metaProperty.setProperty(instance, optionalValue);
-               return null;
-             }
-        }
-        throw new MissingPropertyExceptionNoStack(propertyName, theClass);
-    }
-
-    private Object invokeMissingMethod(Object instance, String methodName, Object[] arguments, RuntimeException original, boolean isCallToSuper) {
-        if (!isCallToSuper) {
-            Class instanceKlazz = instance.getClass();
-            if (theClass != instanceKlazz && theClass.isAssignableFrom(instanceKlazz))
-              instanceKlazz = theClass;
-
-            Class[] argClasses = MetaClassHelper.castArgumentsToClassArray(arguments);
-
-            MetaMethod method = findMixinMethod(methodName, argClasses);
-            if(method != null) {
-                onMixinMethodFound(method);
-                return method.invoke(instance, arguments);
-            }
-
-            method = findMethodInClassHierarchy(instanceKlazz, methodName, argClasses, this);
-            if(method != null) {
-                onSuperMethodFoundInHierarchy(method);
-                return method.invoke(instance, arguments);
-            }
-
-            // still not method here, so see if there is an invokeMethod method up the hierarchy
-            final Class[] invokeMethodArgs = {String.class, Object[].class};
-            method = findMethodInClassHierarchy(instanceKlazz, INVOKE_METHOD_METHOD, invokeMethodArgs, this );
-            if(method != null && method instanceof ClosureMetaMethod) {
-                onInvokeMethodFoundInHierarchy(method);
-                return method.invoke(instance, invokeMethodArgs);
-            }
-        }
-
-        if (methodMissing != null) {
-            try {
-                return methodMissing.invoke(instance, new Object[]{methodName, arguments});
-            } catch (InvokerInvocationException iie) {
-                if (methodMissing instanceof ClosureMetaMethod && iie.getCause() instanceof MissingMethodException) {
-                    MissingMethodException mme =  (MissingMethodException) iie.getCause();
-                    throw new MissingMethodExecutionFailed(mme.getMethod(), mme.getClass(),
-                                                            mme.getArguments(),mme.isStatic(),mme);
-                }
-                throw iie;
-            } catch (MissingMethodException mme) {
-                if (methodMissing instanceof ClosureMetaMethod)
-                    throw new MissingMethodExecutionFailed(mme.getMethod(), mme.getClass(),
-                                                        mme.getArguments(),mme.isStatic(),mme);
-                else
-                    throw mme;
-            }
-        } else if (original != null) throw original;
-        else throw new MissingMethodExceptionNoStack(methodName, theClass, arguments, false);
-    }
-
-    protected void onSuperPropertyFoundInHierarchy(MetaBeanProperty property) {
-    }
-
-    protected void onMixinMethodFound(MetaMethod method) {
-    }
-
-    protected void onSuperMethodFoundInHierarchy(MetaMethod method) {
-    }
-
-    protected void onInvokeMethodFoundInHierarchy(MetaMethod method) {
-    }
-
-    protected void onSetPropertyFoundInHierarchy(MetaMethod method) {
-    }
-
-    protected void onGetPropertyFoundInHierarchy(MetaMethod method) {
-    }
-
-
-    /**
-     * Hook to deal with the case of MissingProperty for static properties. The method will look attempt to look up
-     * "propertyMissing" handlers and invoke them otherwise thrown a MissingPropertyException
-     *
-     * @param instance      The instance
-     * @param propertyName  The name of the property
-     * @param optionalValue The value in the case of a setter
-     * @param isGetter      True if its a getter
-     * @return The value in the case of a getter or a MissingPropertyException
-     */
-    protected Object invokeStaticMissingProperty(Object instance, String propertyName, Object optionalValue, boolean isGetter) {
-        MetaClass mc = instance instanceof Class ? registry.getMetaClass((Class) instance) : this;
-        if (isGetter) {
-            MetaMethod propertyMissing = mc.getMetaMethod(STATIC_PROPERTY_MISSING, GETTER_MISSING_ARGS);
-            if (propertyMissing != null) {
-                return propertyMissing.invoke(instance, new Object[]{propertyName});
-            }
-        } else {
-            MetaMethod propertyMissing = mc.getMetaMethod(STATIC_PROPERTY_MISSING, SETTER_MISSING_ARGS);
-            if (propertyMissing != null) {
-                return propertyMissing.invoke(instance, new Object[]{propertyName, optionalValue});
-            }
-        }
-
-        if (instance instanceof Class) {
-            throw new MissingPropertyException(propertyName, (Class) instance);
-        }
-        throw new MissingPropertyException(propertyName, theClass);
-    }
-
-
-    /**
-     * Invokes a method on the given receiver for the specified arguments.
-     * The MetaClass will attempt to establish the method to invoke based on the name and arguments provided.
-     *
-     *
-     * @param object The object which the method was invoked on
-     * @param methodName The name of the method
-     * @param originalArguments The arguments to the method
-     *
-     * @return The return value of the method
-     *
-     * @see MetaClass#invokeMethod(Class, Object, String, Object[], boolean, boolean)
-     */
-    public Object invokeMethod(Object object, String methodName, Object[] originalArguments) {
-        return invokeMethod(theClass, object, methodName, originalArguments, false, false);
-    }
-
-    private Object invokeMethodClosure(Object object, String methodName, Object[] arguments) {
-        final MethodClosure mc = (MethodClosure) object;
-        final Object owner = mc.getOwner();
-
-        methodName = mc.getMethod();
-        final Class ownerClass = owner instanceof Class ? (Class) owner : owner.getClass();
-        final MetaClass ownerMetaClass = registry.getMetaClass(ownerClass);
-
-        // To conform to "Least Surprise" principle, try to invoke method with original arguments first, which can match most of use cases
-        try {
-            return ownerMetaClass.invokeMethod(ownerClass, owner, methodName, arguments, false, false);
-        } catch (MissingMethodExceptionNoStack e) {
-            // CONSTRUCTOR REFERENCE
-            if (owner instanceof Class && MethodClosure.NEW.equals(methodName)) {
-                if (ownerClass.isArray()) {
-                    if (0 == arguments.length) {
-                        throw new GroovyRuntimeException("The arguments(specifying size) are required to create array[" + ownerClass.getCanonicalName() + "]");
-                    }
-
-                    int arrayDimension = ArrayTypeUtils.dimension(ownerClass);
-
-                    if (arguments.length > arrayDimension) {
-                        throw new GroovyRuntimeException("The length[" + arguments.length + "] of arguments should not be greater than the dimensions[" + arrayDimension + "] of array[" + ownerClass.getCanonicalName() + "]");
-                    }
-
-                    int[] sizeArray = new int[arguments.length];
-
-                    for (int i = 0, n = sizeArray.length; i < n; i++) {
-                        Object argument = arguments[i];
-
-                        if (argument instanceof Integer) {
-                            sizeArray[i] = (Integer) argument;
-                        } else {
-                            sizeArray[i] = Integer.parseInt(String.valueOf(argument));
-                        }
-                    }
-
-                    Class arrayType =
-                            arguments.length == arrayDimension
-                                    ? ArrayTypeUtils.elementType(ownerClass) // Just for better performance, though we can use reduceDimension only
-                                    : ArrayTypeUtils.reduceDimension(ownerClass, (arrayDimension - arguments.length));
-                    return Array.newInstance(arrayType, sizeArray);
-                }
-
-                return ownerMetaClass.invokeConstructor(arguments);
-            }
-
-            // METHOD REFERENCE
-            // if and only if the owner is a class and the method closure can be related to some instance methods,
-            // try to invoke method with adjusted arguments(first argument is the actual owner) again.
-            // otherwise throw the MissingMethodExceptionNoStack.
-            if (!(owner instanceof Class
-                    && ((Boolean) mc.getProperty(MethodClosure.ANY_INSTANCE_METHOD_EXISTS)).booleanValue())) {
-
-                throw e;
-            }
-
-            if (arguments.length <= 0) {
-                return invokeMissingMethod(object, methodName, arguments);
-            }
-
-            Object newOwner = arguments[0];
-            Object[] newArguments = Arrays.copyOfRange(arguments, 1, arguments.length);
-            return ownerMetaClass.invokeMethod(ownerClass, newOwner, methodName, newArguments, false, false);
-        }
-    }
-
-    /**
-     * <p>Invokes a method on the given receiver for the specified arguments. The sender is the class that invoked the method on the object.
-     * The MetaClass will attempt to establish the method to invoke based on the name and arguments provided.
-     *
-     * <p>The isCallToSuper and fromInsideClass help the Groovy runtime perform optimisations on the call to go directly
-     * to the super class if necessary
-     *
-     * @param sender The java.lang.Class instance that invoked the method
-     * @param object The object which the method was invoked on
-     * @param methodName The name of the method
-     * @param originalArguments The arguments to the method
-     * @param isCallToSuper Whether the method is a call to a super class method
-     * @param fromInsideClass Whether the call was invoked from the inside or the outside of the class
-     *
-     * @return The return value of the method
-     *
-     * @see MetaClass#invokeMethod(Class, Object, String, Object[], boolean, boolean)
-     */
-    public Object invokeMethod(Class sender, Object object, String methodName, Object[] originalArguments, boolean isCallToSuper, boolean fromInsideClass) {
-        checkInitalised();
-        if (object == null) {
-            throw new NullPointerException("Cannot invoke method: " + methodName + " on null object");
-        }
-
-        final Object[] arguments = originalArguments == null ? EMPTY_ARGUMENTS : originalArguments;
-//        final Class[] argClasses = MetaClassHelper.convertToTypeArray(arguments);
-//
-//        unwrap(arguments);
-
-        MetaMethod method = null;
-        if (CLOSURE_CALL_METHOD.equals(methodName) && object instanceof GeneratedClosure) {
-            method = getMethodWithCaching(sender, "doCall", arguments, isCallToSuper);
-        }
-        if (method==null) {
-            method = getMethodWithCaching(sender, methodName, arguments, isCallToSuper);
-        }
-        MetaClassHelper.unwrap(arguments);
-
-        if (method == null)
-            method = tryListParamMetaMethod(sender, methodName, isCallToSuper, arguments);
-
-        final boolean isClosure = object instanceof Closure;
-        if (isClosure) {
-            final Closure closure = (Closure) object;
-            final Object owner = closure.getOwner();
-
-            if (CLOSURE_CALL_METHOD.equals(methodName) || CLOSURE_DO_CALL_METHOD.equals(methodName)) {
-                final Class objectClass = object.getClass();
-                if (objectClass == MethodClosure.class) {
-                    return this.invokeMethodClosure(object, methodName, arguments);
-                } else if (objectClass == CurriedClosure.class) {
-                    final CurriedClosure cc = (CurriedClosure) object;
-                    // change the arguments for an uncurried call
-                    final Object[] curriedArguments = cc.getUncurriedArguments(arguments);
-                    final Class ownerClass = owner instanceof Class ? (Class) owner : owner.getClass();
-                    final MetaClass ownerMetaClass = registry.getMetaClass(ownerClass);
-                    return ownerMetaClass.invokeMethod(owner, methodName, curriedArguments);
-                }
-                if (method==null) invokeMissingMethod(object,methodName,arguments);
-            }
-
-            final Object delegate = closure.getDelegate();
-            final boolean isClosureNotOwner = owner != closure;
-            final int resolveStrategy = closure.getResolveStrategy();
-
-            final Class[] argClasses = MetaClassHelper.convertToTypeArray(arguments);
-
-            switch (resolveStrategy) {
-                case Closure.TO_SELF:
-                    method = closure.getMetaClass().pickMethod(methodName, argClasses);
-                    if (method != null) return method.invoke(closure, arguments);
-                    break;
-                case Closure.DELEGATE_ONLY:
-                    if (method == null && delegate != closure && delegate != null) {
-                        MetaClass delegateMetaClass = lookupObjectMetaClass(delegate);
-                        method = delegateMetaClass.pickMethod(methodName, argClasses);
-                        if (method != null)
-                            return delegateMetaClass.invokeMethod(delegate, methodName, originalArguments);
-                        else if (delegate != closure && (delegate instanceof GroovyObject)) {
-                            return invokeMethodOnGroovyObject(methodName, originalArguments, delegate);
-                        }
-                    }
-                    break;
-                case Closure.OWNER_ONLY:
-                    if (method == null && owner != closure) {
-                        MetaClass ownerMetaClass = lookupObjectMetaClass(owner);
-                        return ownerMetaClass.invokeMethod(owner, methodName, originalArguments);
-                    }
-                    break;
-                case Closure.DELEGATE_FIRST:
-                    if (method == null && delegate != closure && delegate != null) {
-                        MetaClass delegateMetaClass = lookupObjectMetaClass(delegate);
-                        method = delegateMetaClass.pickMethod(methodName, argClasses);
-                        if (method != null)
-                            return delegateMetaClass.invokeMethod(delegate, methodName, originalArguments);
-                    }
-                    if (method == null && owner != closure) {
-                        MetaClass ownerMetaClass = lookupObjectMetaClass(owner);
-                        method = ownerMetaClass.pickMethod(methodName, argClasses);
-                        if (method != null) return ownerMetaClass.invokeMethod(owner, methodName, originalArguments);
-                    }
-                    if (method == null && resolveStrategy != Closure.TO_SELF) {
-                        // still no methods found, test if delegate or owner are GroovyObjects
-                        // and invoke the method on them if so.
-                        MissingMethodException last = null;
-                        if (delegate != closure && (delegate instanceof GroovyObject)) {
-                            try {
-                                return invokeMethodOnGroovyObject(methodName, originalArguments, delegate);
-                            } catch (MissingMethodException mme) {
-                                if (last == null) last = mme;
-                            }
-                        }
-                        if (isClosureNotOwner && (owner instanceof GroovyObject)) {
-                            try {
-                                return invokeMethodOnGroovyObject(methodName, originalArguments, owner);
-                            } catch (MissingMethodException mme) {
-                                last = mme;
-                            }
-                        }
-                        if (last != null) return invokeMissingMethod(object, methodName, originalArguments, last, isCallToSuper);
-                    }
-
-                    break;
-                default:
-                    if (method == null && owner != closure) {
-                        MetaClass ownerMetaClass = lookupObjectMetaClass(owner);
-                        method = ownerMetaClass.pickMethod(methodName, argClasses);
-                        if (method != null) return ownerMetaClass.invokeMethod(owner, methodName, originalArguments);
-                    }
-                    if (method == null && delegate != closure && delegate != null) {
-                        MetaClass delegateMetaClass = lookupObjectMetaClass(delegate);
-                        method = delegateMetaClass.pickMethod(methodName, argClasses);
-                        if (method != null)
-                            return delegateMetaClass.invokeMethod(delegate, methodName, originalArguments);
-                    }
-                    if (method == null && resolveStrategy != Closure.TO_SELF) {
-                        // still no methods found, test if delegate or owner are GroovyObjects
-                        // and invoke the method on them if so.
-                        MissingMethodException last = null;
-                        if (isClosureNotOwner && (owner instanceof GroovyObject)) {
-                            try {
-                                return invokeMethodOnGroovyObject(methodName, originalArguments, owner);
-                            } catch (MissingMethodException mme) {
-                                if (methodName.equals(mme.getMethod())) {
-                                    if (last == null) last = mme;
-                                } else {
-                                    throw mme;
-                                }
-                            }
-                            catch (InvokerInvocationException iie) {
-                                if (iie.getCause() instanceof MissingMethodException) {
-                                    MissingMethodException mme = (MissingMethodException) iie.getCause();
-                                    if (methodName.equals(mme.getMethod())) {
-                                        if (last == null) last = mme;
-                                    } else {
-                                        throw iie;
-                                    }
-                                }
-                                else
-                                  throw iie;
-                            }
-                        }
-                        if (delegate != closure && (delegate instanceof GroovyObject)) {
-                            try {
-                                return invokeMethodOnGroovyObject(methodName, originalArguments, delegate);
-                            } catch (MissingMethodException mme) {
-                                last = mme;
-                            }
-                            catch (InvokerInvocationException iie) {
-                                if (iie.getCause() instanceof MissingMethodException) {
-                                    last = (MissingMethodException) iie.getCause();
-                                }
-                                else
-                                  throw iie;
-                            }
-                        }
-                        if (last != null) return invokeMissingMethod(object, methodName, originalArguments, last, isCallToSuper);
-                    }
-            }
-        }
-
-        if (method != null) {
-            return method.doMethodInvoke(object, arguments);
-        } else {
-            return invokePropertyOrMissing(object, methodName, originalArguments, fromInsideClass, isCallToSuper);
-        }
-    }
-
-    private MetaMethod tryListParamMetaMethod(Class sender, String methodName, boolean isCallToSuper, Object[] arguments) {
-        MetaMethod method = null;
-        if (arguments.length == 1 && arguments[0] instanceof List) {
-            Object[] newArguments = ((List) arguments[0]).toArray();
-            method = createTransformMetaMethod(getMethodWithCaching(sender, methodName, newArguments, isCallToSuper));
-        }
-        return method;
-    }
-
-    protected MetaMethod createTransformMetaMethod(MetaMethod method) {
-        if (method == null) {
-            return null;
-        }
-
-        return new TransformMetaMethod(method) {
-            public Object invoke(Object object, Object[] arguments) {
-                Object firstArgument = arguments[0];
-                List list = (List) firstArgument;
-                arguments = list.toArray();
-                return super.invoke(object, arguments);
-            }
-        };
-    }
-
-    private Object invokePropertyOrMissing(Object object, String methodName, Object[] originalArguments, boolean fromInsideClass, boolean isCallToSuper) {
-        // if no method was found, try to find a closure defined as a field of the class and run it
-        Object value = null;
-        final MetaProperty metaProperty = this.getMetaProperty(methodName, false);
-        if (metaProperty != null)
-          value = metaProperty.getProperty(object);
-        else {
-            if (object instanceof Map)
-              value = ((Map)object).get(methodName);
-        }
-
-        if (value instanceof Closure) {  // This test ensures that value != this If you ever change this ensure that value != this
-            Closure closure = (Closure) value;
-            MetaClass delegateMetaClass = closure.getMetaClass();
-            return delegateMetaClass.invokeMethod(closure.getClass(), closure, CLOSURE_DO_CALL_METHOD, originalArguments, false, fromInsideClass);
-        }
-
-        if (object instanceof Script) {
-            Object bindingVar = ((Script) object).getBinding().getVariables().get(methodName);
-            if (bindingVar != null) {
-                MetaClass bindingVarMC = ((MetaClassRegistryImpl) registry).getMetaClass(bindingVar);
-                return bindingVarMC.invokeMethod(bindingVar, CLOSURE_CALL_METHOD, originalArguments);
-            }
-        }
-        return invokeMissingMethod(object, methodName, originalArguments, null, isCallToSuper);
-    }
-
-    private MetaClass lookupObjectMetaClass(Object object) {
-        if (object instanceof GroovyObject) {
-            GroovyObject go = (GroovyObject) object;
-            return go.getMetaClass();
-        }
-        Class ownerClass = object.getClass();
-        if (ownerClass == Class.class) ownerClass = (Class) object;
-        MetaClass metaClass = registry.getMetaClass(ownerClass);
-        return metaClass;
-    }
-
-    private static Object invokeMethodOnGroovyObject(String methodName, Object[] originalArguments, Object owner) {
-        GroovyObject go = (GroovyObject) owner;
-        return go.invokeMethod(methodName, originalArguments);
-    }
-
-    public MetaMethod getMethodWithCaching(Class sender, String methodName, Object[] arguments, boolean isCallToSuper) {
-        // let's try use the cache to find the method
-        if (!isCallToSuper && GroovyCategorySupport.hasCategoryInCurrentThread()) {
-            return getMethodWithoutCaching(sender, methodName, MetaClassHelper.convertToTypeArray(arguments), isCallToSuper);
-        } else {
-            final MetaMethodIndex.Entry e = metaMethodIndex.getMethods(sender, methodName);
-            if (e == null)
-              return null;
-
-            return isCallToSuper ? getSuperMethodWithCaching(arguments, e) : getNormalMethodWithCaching(arguments, e);
-        }
-    }
-
-    private static boolean sameClasses(Class[] params, Class[] arguments) {
-        // we do here a null check because the params field might not have been set yet
-        if (params == null) return false;
-
-        if (params.length != arguments.length)
-            return false;
-
-        for (int i = params.length - 1; i >= 0; i--) {
-            Object arg = arguments[i];
-            if (arg != null) {
-                if (params[i] != arguments[i]) return false;
-            } else return false;
-        }
-
-        return true;
-    }
-
-    // This method should be called by CallSite only
-    private MetaMethod getMethodWithCachingInternal (Class sender, CallSite site, Class [] params) {
-        if (GroovyCategorySupport.hasCategoryInCurrentThread())
-            return getMethodWithoutCaching(sender, site.getName (), params, false);
-
-        final MetaMethodIndex.Entry e = metaMethodIndex.getMethods(sender, site.getName());
-        if (e == null) {
-            return null;
-        }
-
-        MetaMethodIndex.CacheEntry cacheEntry;
-        final Object methods = e.methods;
-        if (methods == null)
-          return null;
-
-        cacheEntry = e.cachedMethod;
-        if (cacheEntry != null && (sameClasses(cacheEntry.params, params))) {
-             return cacheEntry.method;
-        }
-
-        cacheEntry = new MetaMethodIndex.CacheEntry (params, (MetaMethod) chooseMethod(e.name, methods, params));
-        e.cachedMethod = cacheEntry;
-        return cacheEntry.method;
-    }
-
-    private MetaMethod getSuperMethodWithCaching(Object[] arguments, MetaMethodIndex.Entry e) {
-        MetaMethodIndex.CacheEntry cacheEntry;
-        if (e.methodsForSuper == null)
-          return null;
-
-        cacheEntry = e.cachedMethodForSuper;
-
-        if (cacheEntry != null &&
-            MetaClassHelper.sameClasses(cacheEntry.params, arguments, e.methodsForSuper instanceof MetaMethod))
-        {
-            MetaMethod method = cacheEntry.method;
-            if (method!=null) return method;
-        }
-
-        final Class[] classes = MetaClassHelper.convertToTypeArray(arguments);
-        MetaMethod method = (MetaMethod) chooseMethod(e.name, e.methodsForSuper, classes);
-        cacheEntry = new MetaMethodIndex.CacheEntry (classes, method.isAbstract()?null:method);
-
-        e.cachedMethodForSuper = cacheEntry;
-
-        return cacheEntry.method;
-    }
-
-    private MetaMethod getNormalMethodWithCaching(Object[] arguments, MetaMethodIndex.Entry e) {
-        MetaMethodIndex.CacheEntry cacheEntry;
-        final Object methods = e.methods;
-        if (methods == null)
-          return null;
-
-        cacheEntry = e.cachedMethod;
-
-        if (cacheEntry != null &&
-            MetaClassHelper.sameClasses(cacheEntry.params, arguments, methods instanceof MetaMethod))
-        {
-            MetaMethod method = cacheEntry.method;
-            if (method!=null) return method;
-        }
-
-        final Class[] classes = MetaClassHelper.convertToTypeArray(arguments);
-        cacheEntry = new MetaMethodIndex.CacheEntry (classes, (MetaMethod) chooseMethod(e.name, methods, classes));
-
-        e.cachedMethod = cacheEntry;
-
-        return cacheEntry.method;
-    }
-
-    public Constructor retrieveConstructor(Class[] arguments) {
-        CachedConstructor constructor = (CachedConstructor) chooseMethod("<init>", constructors, arguments);
-        if (constructor != null) {
-            return constructor.cachedConstructor;
-        }
-        constructor = (CachedConstructor) chooseMethod("<init>", constructors, arguments);
-        if (constructor != null) {
-            return constructor.cachedConstructor;
-        }
-        return null;
-    }
-
-    public MetaMethod retrieveStaticMethod(String methodName, Object[] arguments) {
-        final MetaMethodIndex.Entry e = metaMethodIndex.getMethods(theClass, methodName);
-        MetaMethodIndex.CacheEntry cacheEntry;
-        if (e != null) {
-            cacheEntry = e.cachedStaticMethod;
-
-            if (cacheEntry != null &&
-                MetaClassHelper.sameClasses(cacheEntry.params, arguments, e.staticMethods instanceof MetaMethod))
-            {
-                 return cacheEntry.method;
-            }
-
-            final Class[] classes = MetaClassHelper.convertToTypeArray(arguments);
-            cacheEntry = new MetaMethodIndex.CacheEntry (classes, pickStaticMethod(methodName, classes));
-
-            e.cachedStaticMethod = cacheEntry;
-
-            return cacheEntry.method;
-        }
-        else
-          return pickStaticMethod(methodName, MetaClassHelper.convertToTypeArray(arguments));
-    }
-
-    public MetaMethod getMethodWithoutCaching(Class sender, String methodName, Class[] arguments, boolean isCallToSuper) {
-        MetaMethod method = null;
-        Object methods = getMethods(sender, methodName, isCallToSuper);
-        if (methods != null) {
-            method = (MetaMethod) chooseMethod(methodName, methods, arguments);
-        }
-        return method;
-    }
-
-    public Object invokeStaticMethod(Object object, String methodName, Object[] arguments) {
-        checkInitalised();
-
-        final Class sender = object instanceof Class ? (Class) object : object.getClass();
-        if (sender != theClass) {
-            MetaClass mc = registry.getMetaClass(sender);
-            return mc.invokeStaticMethod(sender, methodName, arguments);
-        }
-        if (sender == Class.class) {
-            return invokeMethod(object, methodName, arguments);
-        }
-
-        if (arguments == null) arguments = EMPTY_ARGUMENTS;
-//        Class[] argClasses = MetaClassHelper.convertToTypeArray(arguments);
-
-        MetaMethod method = retrieveStaticMethod(methodName, arguments);
-        // let's try use the cache to find the method
-
-        if (method != null) {
-            MetaClassHelper.unwrap(arguments);
-            return method.doMethodInvoke(object, arguments);
-        }
-        Object prop = null;
-        try {
-            prop = getProperty(theClass, theClass, methodName, false, false);
-        } catch (MissingPropertyException mpe) {
-            // ignore
-        }
-
-        if (prop instanceof Closure) {
-            return invokeStaticClosureProperty(arguments, prop);
-        }
-
-        Object[] originalArguments = arguments.clone();
-        MetaClassHelper.unwrap(arguments);
-
-        Class superClass = sender.getSuperclass();
-        Class[] argClasses = MetaClassHelper.convertToTypeArray(arguments);
-        while (superClass != Object.class && superClass != null) {
-            MetaClass mc = registry.getMetaClass(superClass);
-            method = mc.getStaticMetaMethod(methodName, argClasses);
-            if (method != null) return method.doMethodInvoke(object, arguments);
-
-            try {
-                prop = mc.getProperty(superClass, superClass, methodName, false, false);
-            } catch (MissingPropertyException mpe) {
-                // ignore
-            }
-
-            if (prop instanceof Closure) {
-                return invokeStaticClosureProperty(originalArguments, prop);
-            }
-
-            superClass = superClass.getSuperclass();
-        }
-
-        if (prop != null) {
-            MetaClass propMC = registry.getMetaClass(prop.getClass());
-            return propMC.invokeMethod(prop, CLOSURE_CALL_METHOD, arguments);
-        }
-
-        return invokeStaticMissingMethod(sender, methodName, arguments);
-    }
-
-    private static Object invokeStaticClosureProperty(Object[] originalArguments, Object prop) {
-        Closure closure = (Closure) prop;
-        MetaClass delegateMetaClass = closure.getMetaClass();
-        return delegateMetaClass.invokeMethod(closure.getClass(), closure, CLOSURE_DO_CALL_METHOD, originalArguments, false, false);
-    }
-
-    private Object invokeStaticMissingMethod(Class sender, String methodName, Object[] arguments) {
-        MetaMethod metaMethod = getStaticMetaMethod(STATIC_METHOD_MISSING, METHOD_MISSING_ARGS);
-        if (metaMethod != null) {
-            return metaMethod.invoke(sender, new Object[]{methodName, arguments});
-        }
-        throw new MissingMethodException(methodName, sender, arguments, true);
-    }
-
-    private MetaMethod pickStaticMethod(String methodName, Class[] arguments) {
-        MetaMethod method = null;
-        MethodSelectionException mse = null;
-        Object methods = getStaticMethods(theClass, methodName);
-
-        if (!(methods instanceof FastArray) || !((FastArray)methods).isEmpty()) {
-            try {
-                method = (MetaMethod) chooseMethod(methodName, methods, arguments);
-            } catch(MethodSelectionException msex) {
-                mse = msex;
-            }
-        }
-        if (method == null && theClass != Class.class) {
-            MetaClass classMetaClass = registry.getMetaClass(Class.class);
-            method = classMetaClass.pickMethod(methodName, arguments);
-        }
-        if (method == null) {
-            method = (MetaMethod) chooseMethod(methodName, methods, MetaClassHelper.convertToTypeArray(arguments));
-        }
-
-        if (method == null && mse != null) {
-            throw mse;
-        } else {
-            return method;
-        }
-    }
-
-    public Object invokeConstructor(Object[] arguments) {
-        return invokeConstructor(theClass, arguments);
-    }
-
-    public int selectConstructorAndTransformArguments(int numberOfConstructors, Object[] arguments) {
-        if (numberOfConstructors==-1) {
-            return selectConstructorAndTransformArguments1(arguments);
-        } else {
-            // falling back to pre 2.1.9 selection algorithm
-            // in practice this branch will only be reached if the class calling this code is a Groovy class
-            // compiled with an earlier version of the Groovy compiler
-            return selectConstructorAndTransformArguments0(numberOfConstructors, arguments);
-        }
-
-
-    }
-
-    private int selectConstructorAndTransformArguments0(final int numberOfConstructors, Object[] arguments) {
-        //TODO: that is just a quick prototype, not the real thing!
-        if (numberOfConstructors != constructors.size()) {
-            throw new IncompatibleClassChangeError("the number of constructors during runtime and compile time for " +
-                    this.theClass.getName() + " do not match. Expected " + numberOfConstructors + " but got " + constructors.size());
-        }
-
-        CachedConstructor constructor = createCachedConstructor(arguments);
-        List l = new ArrayList(constructors.toList());
-        Comparator comp = new Comparator() {
-            public int compare(Object arg0, Object arg1) {
-                CachedConstructor c0 = (CachedConstructor) arg0;
-                CachedConstructor c1 = (CachedConstructor) arg1;
-                String descriptor0 = BytecodeHelper.getMethodDescriptor(Void.TYPE, c0.getNativeParameterTypes());
-                String descriptor1 = BytecodeHelper.getMethodDescriptor(Void.TYPE, c1.getNativeParameterTypes());
-                return descriptor0.compareTo(descriptor1);
-            }
-        };
-        Collections.sort(l, comp);
-        int found = -1;
-        for (int i = 0; i < l.size(); i++) {
-            if (l.get(i) != constructor) continue;
-            found = i;
-            break;
-        }
-        // NOTE: must be changed to "1 |" if constructor was vargs
-        return 0 | (found << 8);
-    }
-
-    private CachedConstructor createCachedConstructor(Object[] arguments) {
-        if (arguments == null) arguments = EMPTY_ARGUMENTS;
-        Class[] argClasses = MetaClassHelper.convertToTypeArray(arguments);
-        MetaClassHelper.unwrap(arguments);
-        CachedConstructor constructor = (CachedConstructor) chooseMethod("<init>", constructors, argClasses);
-        if (constructor == null) {
-            constructor = (CachedConstructor) chooseMethod("<init>", constructors, argClasses);
-        }
-        if (constructor == null) {
-            throw new GroovyRuntimeException(
-                    "Could not find matching constructor for: "
-                            + theClass.getName()
-                            + "(" + InvokerHelper.toTypeString(arguments) + ")");
-        }
-        return constructor;
-    }
-
-    /**
-     * Constructor selection algorithm for Groovy 2.1.9+.
-     * This selection algorithm was introduced as a workaround for GROOVY-6080. Instead of generating an index between
-     * 0 and N where N is the number of super constructors at the time the class is compiled, this algorithm uses
-     * a hash of the constructor descriptor instead.
-     *
-     * This has the advantage of letting the super class add new constructors while being binary compatible. But there
-     * are still problems with this approach:
-     * <ul>
-     *     <li>There's a risk of hash collision, even if it's very low (two constructors of the same class must have the same hash)</li>
-     *     <li>If the super class adds a new constructor which takes as an argument a superclass of an existing constructor parameter and
-     *     that this new constructor is selected at runtime, it would not find it.</li>
-     * </ul>
-     *
-     * Hopefully in the last case, the error message is much nicer now since it explains that it's a binary incompatible change.
-     *
-     * @param arguments the actual constructor call arguments
-     * @return a hash used to identify the constructor to be called
-     * @since 2.1.9
-     */
-    private int selectConstructorAndTransformArguments1(Object[] arguments) {
-        CachedConstructor constructor = createCachedConstructor(arguments);
-        final String methodDescriptor = BytecodeHelper.getMethodDescriptor(Void.TYPE, constructor.getNativeParameterTypes());
-        // keeping 3 bits for additional information such as vargs
-        return BytecodeHelper.hashCode(methodDescriptor);
-    }
-
-
-    /**
-     * checks if the initialisation of the class id complete.
-     * This method should be called as a form of assert, it is no
-     * way to test if there is still initialisation work to be done.
-     * Such logic must be implemented in a different way.
-     *
-     * @throws IllegalStateException if the initialisation is incomplete yet
-     */
-    protected void checkInitalised() {
-        if (!isInitialized())
-            throw new IllegalStateException(
-                    "initialize must be called for meta " +
-                            "class of " + theClass +
-                            "(" + this.getClass() + ") " +
-                            "to complete initialisation process " +
-                            "before any invocation or field/property " +
-                            "access can be done");
-    }
-
-    /**
-     * This is a helper class introduced in Groovy 2.1.0, which is used only by
-     * indy. This class is for internal use only.
-     * @since Groovy 2.1.0
-     */
-    public static final class MetaConstructor extends MetaMethod {
-        private final CachedConstructor cc;
-        private final boolean beanConstructor;
-        private MetaConstructor(CachedConstructor cc, boolean bean) {
-            super(cc.getNativeParameterTypes());
-            this.setParametersTypes(cc.getParameterTypes());
-            this.cc = cc;
-            this.beanConstructor = bean;
-        }
-        @Override
-        public int getModifiers() { return cc.getModifiers(); }
-        @Override
-        public String getName() { return "<init>"; }
-        @Override
-        public Class getReturnType() { return cc.getCachedClass().getTheClass(); }
-        @Override
-        public CachedClass getDeclaringClass() { return cc.getCachedClass(); }
-        @Override
-        public Object invoke(Object object, Object[] arguments) {
-            return cc.doConstructorInvoke(arguments);
-        }
-        public CachedConstructor getCachedConstrcutor() { return cc; }
-        public boolean isBeanConstructor() { return beanConstructor; }
-    }
-
-    /**
-     * This is a helper method added in Groovy 2.1.0, which is used only by indy.
-     * This method is for internal use only.
-     * @since Groovy 2.1.0
-     */
-    public MetaMethod retrieveConstructor(Object[] arguments) {
-        checkInitalised();
-        if (arguments == null) arguments = EMPTY_ARGUMENTS;
-        Class[] argClasses = MetaClassHelper.convertToTypeArray(arguments);
-        MetaClassHelper.unwrap(arguments);
-        Object res = chooseMethod("<init>", constructors, argClasses);
-        if (res instanceof MetaMethod) return (MetaMethod) res;
-        CachedConstructor constructor = (CachedConstructor) res;
-        if (constructor != null) return new MetaConstructor(constructor, false);
-        if (arguments.length == 1 && arguments[0] instanceof Map) {
-            res = chooseMethod("<init>", constructors, MetaClassHelper.EMPTY_TYPE_ARRAY);
-        } else if (
-                arguments.length == 2 && arguments[1] instanceof Map &&
-                theClass.getEnclosingClass()!=null &&
-                theClass.getEnclosingClass().isAssignableFrom(argClasses[0]))
-        {
-            res = chooseMethod("<init>", constructors, new Class[]{argClasses[0]});
-        }
-        if (res instanceof MetaMethod) return (MetaMethod) res;
-        constructor = (CachedConstructor) res;
-        if (constructor != null) return new MetaConstructor(constructor, true);
-
-        return null;
-    }
-
-    private Object invokeConstructor(Class at, Object[] arguments) {
-        checkInitalised();
-        if (arguments == null) arguments = EMPTY_ARGUMENTS;
-        Class[] argClasses = MetaClassHelper.convertToTypeArray(arguments);
-        MetaClassHelper.unwrap(arguments);
-        CachedConstructor constructor = (CachedConstructor) chooseMethod("<init>", constructors, argClasses);
-        if (constructor != null) {
-            return constructor.doConstructorInvoke(arguments);
-        }
-
-        if (arguments.length == 1) {
-            Object firstArgument = arguments[0];
-            if (firstArgument instanceof Map) {
-                constructor = (CachedConstructor) chooseMethod("<init>", constructors, MetaClassHelper.EMPTY_TYPE_ARRAY);
-                if (constructor != null) {
-                    Object bean = constructor.doConstructorInvoke(MetaClassHelper.EMPTY_ARRAY);
-                    setProperties(bean, ((Map) firstArgument));
-                    return bean;
-                }
-            }
-        }
-        throw new GroovyRuntimeException(
-                "Could not find matching constructor for: "
-                        + theClass.getName()
-                        + "(" + InvokerHelper.toTypeString(arguments) + ")");
-    }
-
-    /**
-     * Sets a number of bean properties from the given Map where the keys are
-     * the String names of properties and the values are the values of the
-     * properties to set
-     */
-    public void setProperties(Object bean, Map map) {
-        checkInitalised();
-        for (Iterator iter = map.entrySet().iterator(); iter.hasNext();) {
-            Map.Entry entry = (Map.Entry) iter.next();
-            String key = entry.getKey().toString();
-
-            Object value = entry.getValue();
-            setProperty(bean, key, value);
-        }
-    }
-
-    /**
-     * @return the given property's value on the object
-     */
-    public Object getProperty(Class sender, Object object, String name, boolean useSuper, boolean fromInsideClass) {
-
-        //----------------------------------------------------------------------
-        // handling of static
-        //----------------------------------------------------------------------
-        boolean isStatic = theClass != Class.class && object instanceof Class;
-        if (isStatic && object != theClass) {
-            MetaClass mc = registry.getMetaClass((Class) object);
-            return mc.getProperty(sender, object, name, useSuper, false);
-        }
-
-        checkInitalised();
-
-        //----------------------------------------------------------------------
-        // turn getProperty on a Map to get on the Map itself
-        //----------------------------------------------------------------------
-        if (!isStatic && this.isMap) {
-            return ((Map) object).get(name);
-        }
-
-        Tuple2<MetaMethod, MetaProperty> methodAndProperty = createMetaMethodAndMetaProperty(sender, sender, name, useSuper, isStatic);
-        MetaMethod method = methodAndProperty.getFirst();
-
-        //----------------------------------------------------------------------
-        // getter
-        //----------------------------------------------------------------------
-        MetaProperty mp = methodAndProperty.getSecond();
-
-        //----------------------------------------------------------------------
-        // field
-        //----------------------------------------------------------------------
-        if (method == null && mp != null) {
-            try {
-                return mp.getProperty(object);
-            } catch (IllegalArgumentException e) {
-                // can't access the field directly but there may be a getter
-                mp = null;
-            } catch (CacheAccessControlException e) {
-                // can't access the field directly but there may be a getter
-                mp = null;
-            }
-        }
-
-        //----------------------------------------------------------------------
-        // generic get method
-        //----------------------------------------------------------------------
-        // check for a generic get method provided through a category
-        Object[] arguments = EMPTY_ARGUMENTS;
-        if (method == null && !useSuper && !isStatic && GroovyCategorySupport.hasCategoryInCurrentThread()) {
-            method = getCategoryMethodGetter(sender, "get", true);
-            if (method != null) arguments = new Object[]{name};
-        }
-
-        // the generic method is valid, if available (!=null), if static or
-        // if it is not static and we do no static access
-        if (method == null && genericGetMethod != null && !(!genericGetMethod.isStatic() && isStatic)) {
-            arguments = new Object[]{name};
-            method = genericGetMethod;
-        }
-
-        //----------------------------------------------------------------------
-        // special cases
-        //----------------------------------------------------------------------
-        if (method == null) {
-            /** todo these special cases should be special MetaClasses maybe */
-            if (theClass != Class.class && object instanceof Class) {
-                MetaClass mc = registry.getMetaClass(Class.class);
-                return mc.getProperty(Class.class, object, name, useSuper, false);
-            } else if (object instanceof Collection) {
-                return DefaultGroovyMethods.getAt((Collection) object, name);
-            } else if (object instanceof Object[]) {
-                return DefaultGroovyMethods.getAt(Arrays.asList((Object[]) object), name);
-            } else {
-                MetaMethod addListenerMethod = listeners.get(name);
-                if (addListenerMethod != null) {
-                    //TODO: one day we could try return the previously registered Closure listener for easy removal
-                    return null;
-                }
-            }
-        } else {
-
-            //----------------------------------------------------------------------
-            // executing the getter method
-            //----------------------------------------------------------------------
-            return method.doMethodInvoke(object, arguments);
-        }
-
-        //----------------------------------------------------------------------
-        // error due to missing method/field
-        //----------------------------------------------------------------------
-        if (isStatic || object instanceof Class)
-            return invokeStaticMissingProperty(object, name, null, true);
-        else
-            return invokeMissingProperty(object, name, null, true);
-    }
-
-    public MetaProperty getEffectiveGetMetaProperty(final Class sender, final Object object, String name, final boolean useSuper) {
-
-        //----------------------------------------------------------------------
-        // handling of static
-        //----------------------------------------------------------------------
-        boolean isStatic = theClass != Class.class && object instanceof Class;
-        if (isStatic && object != theClass) {
-            return new MetaProperty(name, Object.class) {
-                final MetaClass mc = registry.getMetaClass((Class) object);
-
-                public Object getProperty(Object object) {
-                    return mc.getProperty(sender, object, name, useSuper,false);
-                }
-
-                publ

<TRUNCATED>