http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/groovy/lang/MetaClassRegistry.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/MetaClassRegistry.java 
b/src/main/groovy/groovy/lang/MetaClassRegistry.java
new file mode 100644
index 0000000..f13c1c1
--- /dev/null
+++ b/src/main/groovy/groovy/lang/MetaClassRegistry.java
@@ -0,0 +1,192 @@
+/*
+ *  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.codehaus.groovy.runtime.GeneratedClosure;
+import org.codehaus.groovy.runtime.metaclass.ClosureMetaClass;
+
+import java.lang.reflect.Constructor;
+import java.util.Iterator;
+
+/**
+ * A MetaClassRegistry is an object that is responsible for managing the a 
cache of MetaClass instances. Each
+ * java.lang.Class instance has an associated MetaClass and client code can 
query this interface for the MetaClass for
+ * a given associated java.lang.Class
+ *
+ * @see groovy.lang.MetaClass
+ *
+ * @author John Wilson
+ * @author Graeme Rocher
+ * @author <a href="mailto:[email protected]";>Jochen Theodorou</a>
+ *
+ */
+public interface MetaClassRegistry {
+    
+    /**
+     * The main function of the registry
+     * If a meta class exists then return it
+     * otherwise create one, put it in the registry and return it
+     */
+    MetaClass getMetaClass(Class theClass);
+    
+    /**
+     * Adds a metaclass to the registry for the given class
+     *
+     * @param theClass The class
+     * @param theMetaClass The MetaClass for theClass
+     */
+    void setMetaClass(Class theClass, MetaClass theMetaClass);
+
+    /**
+     * Removes a cached MetaClass from the registry
+     *
+     * @param theClass The Java class of the MetaClass to remove
+     */
+    void removeMetaClass(Class theClass);
+
+    /**
+     * Retrieves the MetaClassCreationHandle that is responsible for 
constructing MetaClass instances
+     *
+     * @return The MetaClassCreationHandle instance
+     */
+    MetaClassCreationHandle getMetaClassCreationHandler();
+
+    /**
+     * Sets the MetaClassCreationHandle instance that is responsible for 
constructing instances
+     *
+     * @param handle The handle instance
+     */
+    void setMetaClassCreationHandle(MetaClassCreationHandle handle);
+
+    /**
+     * Adds a meta class change listener for constant meta classes
+     *
+     * @param listener - the update listener
+     */
+    void 
addMetaClassRegistryChangeEventListener(MetaClassRegistryChangeEventListener 
listener);
+    
+    /**
+     * Adds a meta class change listener for constant meta classes. 
+     * This listener cannot be removed!
+     *
+     * @param listener - the update listener
+     */
+    void 
addNonRemovableMetaClassRegistryChangeEventListener(MetaClassRegistryChangeEventListener
 listener);
+
+    /**
+     * Removes a meta class change listener for constant meta classes
+     *
+     * @param listener - the update listener
+     */
+    void 
removeMetaClassRegistryChangeEventListener(MetaClassRegistryChangeEventListener 
listener);
+
+    /**
+     * Returns all registered class change listener for constant meta classes.
+     *
+     * @return an array containing all change listener
+     */
+    MetaClassRegistryChangeEventListener[] 
getMetaClassRegistryChangeEventListeners();
+
+    /**
+     * Gets a snapshot of the current constant meta classes and returns it as 
Iterator.
+     * Modifications done using this Iterator will not cause a 
ConcurrentModificationException.
+     * If a MetaClass is removed using this Iterator, then the MetaClass will 
only
+     * be removed if the MetaClass was not replaced by another MetaClass in 
the meantime.
+     * If a MetaClass is added while using this Iterator, then it will be part 
of the Iteration.
+     * If a MetaClass replaces another constant meta class, then the Iteration 
might show two
+     * meta classes for the same class.
+     * <p>
+     * Note: This Iterator may not used with multiple threads.
+     *
+     * @return Iterator for the constant meta classes
+     */
+    Iterator iterator();    
+    
+    /**
+     * Class used as base for the creation of MetaClass implementations.
+     * The Class defaults to MetaClassImpl, if the class loading fails to
+     * find a special meta class. The name for such a meta class would be
+     * the class name it is created for with the prefix
+     * "groovy.runtime.metaclass." By replacing the handle in the registry
+     * you can have any control over the creation of what MetaClass is used
+     * for a class that you want to have. 
+     * WARNING: experimental code, likely to change soon
+     * @author Jochen Theodorou
+     */
+    class MetaClassCreationHandle {
+        private boolean disableCustomMetaClassLookup;
+         
+        /**
+         * Creates a metaclass implementation for theClass.
+         * @param theClass The class to create a metaclass for
+         * @param registry The metaclass registry the metaclass we be 
registered in.
+         */
+        public final MetaClass create(Class theClass, MetaClassRegistry 
registry) {
+           if (disableCustomMetaClassLookup)
+               return createNormalMetaClass(theClass, registry);
+
+            return createWithCustomLookup(theClass, registry);
+        }
+
+        private MetaClass createWithCustomLookup(Class theClass, 
MetaClassRegistry registry) {
+            try {
+                final Class customMetaClass = 
Class.forName("groovy.runtime.metaclass." + theClass.getName() + "MetaClass");
+                if 
(DelegatingMetaClass.class.isAssignableFrom(customMetaClass)) {
+                    final Constructor customMetaClassConstructor = 
customMetaClass.getConstructor(MetaClass.class);
+                    MetaClass normalMetaClass = 
createNormalMetaClass(theClass, registry);
+                    return 
(MetaClass)customMetaClassConstructor.newInstance(normalMetaClass);
+                }
+                else {
+                    final Constructor customMetaClassConstructor = 
customMetaClass.getConstructor(MetaClassRegistry.class, Class.class);
+                    return 
(MetaClass)customMetaClassConstructor.newInstance(registry, theClass);
+                }
+            }
+            catch (final ClassNotFoundException e) {
+                return createNormalMetaClass(theClass, registry);
+            } catch (final Exception e) {
+                throw new GroovyRuntimeException("Could not instantiate custom 
Metaclass for class: " + theClass.getName() + ". Reason: " + e, e);
+            }
+        }
+
+        protected MetaClass createNormalMetaClass(Class 
theClass,MetaClassRegistry registry) {
+            if (GeneratedClosure.class.isAssignableFrom(theClass)) {
+                return new ClosureMetaClass(registry,theClass);
+            } else {
+                return new MetaClassImpl(registry, theClass);
+            }
+        }
+
+        /**
+         * Returns whether custom meta classes are disabled.
+         */
+        public boolean isDisableCustomMetaClassLookup() {
+            return disableCustomMetaClassLookup;
+        }
+
+        /**
+         * Set flag saying to disable lookup of custom meta classes
+         * It's enough to call this method only once in your application for 
handle which was set in to registry
+         * as every new handle will inherit this property
+         * @param disableCustomMetaClassLookup flag saying to disable lookup 
of custom meta classes
+         */
+        public void setDisableCustomMetaClassLookup(boolean 
disableCustomMetaClassLookup) {
+            this.disableCustomMetaClassLookup = disableCustomMetaClassLookup;
+        }
+    }
+ }

http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/groovy/lang/MetaClassRegistryChangeEvent.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/MetaClassRegistryChangeEvent.java 
b/src/main/groovy/groovy/lang/MetaClassRegistryChangeEvent.java
new file mode 100644
index 0000000..c882fda
--- /dev/null
+++ b/src/main/groovy/groovy/lang/MetaClassRegistryChangeEvent.java
@@ -0,0 +1,104 @@
+/*
+ *  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 java.util.EventObject;
+
+/**
+ * An event used to propagate meta class updates
+ *
+ * @author <a href="mailto:[email protected]";>Jochen Theodorou</a>
+ */
+public class MetaClassRegistryChangeEvent extends EventObject {
+    private final Class clazz;
+    private final Object instance;
+    private final MetaClass metaClass;
+    private final MetaClass oldMetaClass;
+
+    /**
+     *Constructs a new MetaClassRegistryChangeEvent Object
+     *
+     * @param source The object the the event originates at.
+     * @param instance Object instance  the MetaClass change is on.
+     * @param clazz  The class that is affected by the registry change
+     * @param oldMetaClass The old MetaClass
+     * @param newMetaClass The new MetaClass
+     */
+    public MetaClassRegistryChangeEvent(Object source, Object instance, Class 
clazz, MetaClass oldMetaClass, MetaClass newMetaClass) {
+        super(source);
+        this.clazz = clazz;
+        this.metaClass = newMetaClass;
+        this.oldMetaClass = oldMetaClass;
+        this.instance = instance;
+    }
+
+    /**
+     * Get the class that is updated.
+     *
+     *@return The updated class
+     */
+    public Class getClassToUpdate() {
+        return clazz;
+    }
+
+    /**
+     * Get the new MetaClass
+     *
+     * @return The new MetaClass
+     */
+    public MetaClass getNewMetaClass() {
+        return metaClass;
+    }
+
+    /**
+     * Get the old MetaClass
+     *
+     * @return The old MetaClass
+     */
+    public MetaClass getOldMetaClass() {
+        return oldMetaClass;
+    }
+
+    /**
+     * Determines if this event is for a change for a single instance or all 
instances of the Class.
+     *
+     * @return whether this event is for a single instance
+     */
+    public boolean isPerInstanceMetaClassChange() {
+        return instance!=null;
+    }
+
+    /**
+     * Returns the instance this event is for.
+     *
+     * @return the instance or null if this event is for a change for all 
instances of a class
+     */
+    public Object getInstance() {
+        return instance;
+    }
+
+    /**
+     * Get the MetaClassRegistry that originates this change
+     *
+     * @return the source MetaClassRegistry
+     */
+    public MetaClassRegistry getRegistry() {
+        return (MetaClassRegistry) source;
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/groovy/lang/MetaClassRegistryChangeEventListener.java
----------------------------------------------------------------------
diff --git 
a/src/main/groovy/groovy/lang/MetaClassRegistryChangeEventListener.java 
b/src/main/groovy/groovy/lang/MetaClassRegistryChangeEventListener.java
new file mode 100644
index 0000000..e7fd40c
--- /dev/null
+++ b/src/main/groovy/groovy/lang/MetaClassRegistryChangeEventListener.java
@@ -0,0 +1,42 @@
+/*
+ *  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 java.util.EventListener;
+
+/**
+ * A listener called whenever a constant MetaClass is set, removed or 
replaced. 
+ *
+ * @see groovy.lang.MetaClassRegistry
+ * @see groovy.lang.MetaClassRegistryChangeEvent
+ *
+ * @author <a href="mailto:[email protected]";>Jochen Theodorou</a>
+  *
+ */
+public interface MetaClassRegistryChangeEventListener extends EventListener{
+
+    /**
+     * Called when the a constant MetaClass is updated. If the new MetaClass 
is null, then the MetaClass
+     * is removed. Be careful, while this method is executed other updates may 
happen. If you want this
+     * method thread safe, you have to take care of that by yourself.
+     *
+     * @param cmcu - the change event
+     */
+    void updateConstantMetaClass(MetaClassRegistryChangeEvent cmcu);
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/groovy/lang/MetaExpandoProperty.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/MetaExpandoProperty.java 
b/src/main/groovy/groovy/lang/MetaExpandoProperty.java
new file mode 100644
index 0000000..6eb2cf7
--- /dev/null
+++ b/src/main/groovy/groovy/lang/MetaExpandoProperty.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.lang;
+
+import java.util.Map.Entry;
+
+/**
+ * Represents a property in an Expando object
+ *
+ * @author John Stump
+ */
+public class MetaExpandoProperty extends MetaProperty {
+
+    Object value = null;
+
+    public MetaExpandoProperty(Entry entry) {
+        super((String) entry.getKey(), Object.class);
+
+        value = entry.getValue();
+    }
+
+    /**
+     * @return the property of the given object
+     * @throws Exception if the property could not be evaluated
+     */
+    public Object getProperty(Object object) {
+        return value;
+    }
+
+    /**
+     * Sets the property on the given object to the new value
+     *
+     * @param object   on which to set the property
+     * @param newValue the new value of the property
+     */
+    public void setProperty(Object object, Object newValue) {
+        value = newValue;
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/groovy/lang/MetaMethod.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/MetaMethod.java 
b/src/main/groovy/groovy/lang/MetaMethod.java
new file mode 100644
index 0000000..3051675
--- /dev/null
+++ b/src/main/groovy/groovy/lang/MetaMethod.java
@@ -0,0 +1,330 @@
+/*
+ *  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.codehaus.groovy.classgen.asm.BytecodeHelper;
+import org.codehaus.groovy.reflection.CachedClass;
+import org.codehaus.groovy.reflection.ParameterTypes;
+import org.codehaus.groovy.runtime.InvokerHelper;
+import org.codehaus.groovy.runtime.MetaClassHelper;
+
+import java.lang.reflect.Modifier;
+
+/**
+ * Represents a Method on a Java object a little like {@link 
java.lang.reflect.Method}
+ * except without using reflection to invoke the method
+ *
+ * @author <a href="mailto:[email protected]";>James Strachan</a>
+ * @author Alex Tkachman
+ */
+public abstract class MetaMethod extends ParameterTypes implements Cloneable {
+    private String signature;
+    private String mopName;
+
+    /**
+     * Constructor for a metamethod with an empty parameter list
+     */
+    public MetaMethod() {
+    }
+
+    /**
+     *Constructor wit a list of parameter classes
+     *
+     * @param pt A list of parameters types
+     */
+    public MetaMethod(Class [] pt) {
+        super (pt);
+    }
+
+    /**
+     *Returns the modifiers for this method
+     *
+     * @return modifiers as an int.
+     */
+    public abstract int getModifiers();
+
+    /**
+     * Returns the name of the method represented by this class
+     * 
+     * @return name of this method
+     */
+    public abstract String getName();
+
+    /**
+     * Access the return type for this method
+     *
+     *@return the return type of this method
+     */
+    public abstract Class getReturnType();
+
+    /**
+     * Gets the class where this method is declared
+     *
+     * @return class of this method
+     */
+    public abstract CachedClass getDeclaringClass();
+
+    /**
+     * Invoke this method
+     *
+     * @param object The object this method should be invoked on
+     * @param arguments The arguments for the method if applicable
+     * @return The return value of the invocation
+     */
+    public abstract Object invoke(Object object, Object[] arguments);
+
+    /**
+     * Checks that the given parameters are valid to call this method
+     *
+     * @param arguments the arguments to check
+     * @throws IllegalArgumentException if the parameters are not valid
+     */
+    public void checkParameters(Class[] arguments) {
+        // lets check that the argument types are valid
+        if (!isValidMethod(arguments)) {
+            throw new IllegalArgumentException(
+                    "Parameters to method: "
+                    + getName()
+                    + " do not match types: "
+                    + InvokerHelper.toString(getParameterTypes())
+                    + " for arguments: "
+                    + InvokerHelper.toString(arguments));
+        }
+    }
+
+    /**
+     *Returns true if this this metamethod represents the same method as the 
argument.
+     *
+     * @param method A metaMethod instance
+     * @return true if method is for the same method as this method, false 
otherwise.
+     */
+    public boolean isMethod(MetaMethod method) {
+        return getName().equals(method.getName())
+            && getModifiers() == method.getModifiers()
+            && getReturnType().equals(method.getReturnType())
+            && equal(getParameterTypes(), method.getParameterTypes());
+    }
+
+    protected static boolean equal(CachedClass[] a, Class[] b) {
+        if (a.length == b.length) {
+            for (int i = 0, size = a.length; i < size; i++) {
+                if (!a[i].getTheClass().equals(b[i])) {
+                    return false;
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+    protected static boolean equal(CachedClass[] a, CachedClass[] b) {
+        if (a.length == b.length) {
+            for (int i = 0, size = a.length; i < size; i++) {
+                if (a[i] != b[i]) {
+                    return false;
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Returns a string representation of this method
+     */
+    public String toString() {
+        return super.toString()
+            + "[name: "
+            + getName()
+            + " params: "
+            + InvokerHelper.toString(getParameterTypes())
+            + " returns: "
+            + getReturnType()
+            + " owner: "
+            + getDeclaringClass()
+            + "]";
+    }
+
+    public Object clone() {
+        try {
+            return super.clone();
+        }
+        catch (CloneNotSupportedException e) {
+            throw new GroovyRuntimeException("This should never happen", e);
+        }
+    }
+
+    /**
+     * Returns whether or not this method is static.
+     * @return true if this method is static
+     */
+    public boolean isStatic() {
+        return (getModifiers() & Modifier.STATIC) != 0;
+    }
+
+    /**
+     * Returns whether or not this method is abstract.
+     * @return true if this method is abstract
+     */
+    public boolean isAbstract() {
+        return (getModifiers() & Modifier.ABSTRACT) != 0;
+    }
+
+    /**
+     * Returns whether or not this method is private.
+     * @return true if this method is private
+     */
+    public final boolean isPrivate() {
+        return (getModifiers() & Modifier.PRIVATE) != 0;
+    }
+
+    /**
+     * Returns whether or not this method is protected.
+     * @return true if this method is protected
+     */
+    public final boolean isProtected() {
+        return (getModifiers() & Modifier.PROTECTED) != 0;
+    }
+
+    /**
+     * Returns whether or not this method is public.
+     * @return true if this method is public
+     */
+    public final boolean isPublic() {
+        return (getModifiers() & Modifier.PUBLIC) != 0;
+    }
+
+    /**
+     * @param method the method to compare against
+     * @return true if the given method has the same name, parameters, return 
type
+     * and modifiers but may be defined on another type
+     */
+    public final boolean isSame(MetaMethod method) {
+        return getName().equals(method.getName())
+            && compatibleModifiers(getModifiers(), method.getModifiers())
+            && getReturnType().equals(method.getReturnType())
+            && equal(getParameterTypes(), method.getParameterTypes());
+    }
+
+    /**
+     * Checks the compatibility between two modifier masks. Checks that they 
are equal
+     * with regards to access and static modifier.
+     *
+     * @return true if the modifiers are compatible
+     */
+    private static boolean compatibleModifiers(int modifiersA, int modifiersB) 
{
+        int mask = Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC | 
Modifier.STATIC;
+        return (modifiersA & mask) == (modifiersB & mask);
+    }
+
+    /**
+     * Returns whether this object is cacheable
+     */
+    public boolean isCacheable() {
+        return true;
+    }
+
+    /**
+     * Return a descriptor of this method based on the return type and 
parameters of this method.
+     */
+    public String getDescriptor() {
+        return BytecodeHelper.getMethodDescriptor(getReturnType(), 
getNativeParameterTypes());
+    }
+
+    /**
+     * Returns the signature of this method
+     *
+     * @return The signature of this method
+     */
+    public synchronized String getSignature() {
+        if (signature == null) {
+            CachedClass [] parameters = getParameterTypes();
+            final String name = getName();
+            StringBuilder buf = new 
StringBuilder(name.length()+parameters.length*10);
+            buf.append(getReturnType().getName());
+            
+            buf.append(' ');
+            buf.append(name);
+            buf.append('(');
+            for (int i = 0; i < parameters.length; i++) {
+                if (i > 0) {
+                    buf.append(", ");
+                }
+                buf.append(parameters[i].getName());
+            }
+            buf.append(')');
+            signature = buf.toString();
+        }
+        return signature;
+    }
+
+    
+    public String getMopName() {
+        if (mopName == null) {
+          String name = getName();
+          CachedClass declaringClass = getDeclaringClass();
+          if (Modifier.isPrivate(getModifiers()))
+            mopName = new 
StringBuffer().append("this$").append(declaringClass.getSuperClassDistance()).append("$").append(name).toString();
+          else 
+            mopName = new 
StringBuffer().append("super$").append(declaringClass.getSuperClassDistance()).append("$").append(name).toString();
+        }
+        return mopName;
+    }
+
+    /**
+     * This method is called when an exception occurs while invoking this 
method.
+     */
+    public final RuntimeException processDoMethodInvokeException (Exception e, 
Object object, Object [] argumentArray) {
+//        if (e instanceof IllegalArgumentException) {
+//            //TODO: test if this is OK with new MOP, should be changed!
+//            // we don't want the exception being unwrapped if it is a 
IllegalArgumentException
+//            // but in the case it is for example a 
IllegalThreadStateException, we want the unwrapping
+//            // from the runtime
+//            //Note: the reason we want unwrapping sometimes and sometimes 
not is that the method
+//            // invocation tries to invoke the method with and then reacts 
with type transformation
+//            // if the invocation failed here. This is OK for 
IllegalArgumentException, but it is
+//            // possible that a Reflector will be used to execute the call 
and then an Exception from inside
+//            // the method is not wrapped in a InvocationTargetException and 
we will end here.
+//            boolean setReason = e.getClass() != 
IllegalArgumentException.class || this instanceof 
org.codehaus.groovy.reflection.GeneratedMetaMethod;
+//            return MetaClassHelper.createExceptionText("failed to invoke 
method: ", this, object, argumentArray, e, setReason);
+//        }
+
+        if (e instanceof RuntimeException)
+          return (RuntimeException) e;
+
+        return MetaClassHelper.createExceptionText("failed to invoke method: 
", this, object, argumentArray, e, true);
+    }
+
+    /**
+     * Invokes the method this object represents. This method is not final but 
it should be overloaded very carefully and only by generated methods
+     * there is no guarantee that it will be called
+     *
+     * @param object The object the method is to be called at.
+     * @param argumentArray Arguments for the method invocation.
+     * @return The return value of the invoked method.
+     */
+    public Object doMethodInvoke(Object object, Object[] argumentArray) {
+        argumentArray = coerceArgumentsToClasses(argumentArray);
+        try {
+            return invoke(object, argumentArray);
+        } catch (Exception e) {
+            throw processDoMethodInvokeException(e, object, argumentArray);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/groovy/lang/MetaObjectProtocol.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/MetaObjectProtocol.java 
b/src/main/groovy/groovy/lang/MetaObjectProtocol.java
new file mode 100644
index 0000000..4218831
--- /dev/null
+++ b/src/main/groovy/groovy/lang/MetaObjectProtocol.java
@@ -0,0 +1,227 @@
+/*
+ *  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 java.util.List;
+
+/**
+ * <p>An interface that defines the API usable by clients of Groovy's Meta 
Object Protocol (MOP). These methods are
+ * implemented by the reference implementation of the {@link 
groovy.lang.MetaClass} interface.
+ *
+ * @see MetaClassImpl
+ * @author John Wilson
+ * @author Graeme Rocher
+ */
+public interface MetaObjectProtocol {
+
+    /**
+     * Obtain a list of all meta properties available on this meta class
+     *
+     * @see groovy.lang.MetaProperty
+     * @return A list of MetaProperty instances
+     */
+    List<MetaProperty> getProperties();
+    /**
+     * Obtain a list of all the meta methods available on this meta class
+     *
+     * @see groovy.lang.MetaMethod
+     * @return A list of MetaMethod instances
+     */
+    List<MetaMethod> getMethods();
+    
+    /**
+     * <p>Returns an object satisfying Groovy truth if the implementing 
MetaClass responds to
+     * a method with the given name and arguments types.
+     *
+     * <p>Note that this method's return value is based on realised methods 
and does not take into account
+     * objects or classes that implement invokeMethod or methodMissing
+     *
+     * <p>This method is "safe" in that it will always return a value and 
never throw an exception
+     *
+     * @param obj The object to inspect
+     * @param name The name of the method of interest
+     * @param argTypes The argument types to match against
+     * @return A List of MetaMethods matching the argument types which will be 
empty if no matching methods exist
+     */
+    List<MetaMethod> respondsTo(Object obj, String name, Object[] argTypes);
+
+    /**
+     * <p>Returns an object satisfying Groovy truth if the implementing 
MetaClass responds to
+     * a method with the given name regardless of arguments. In other words 
this method will
+     * return for foo() and foo(String).
+     *
+     * <p>Note that this method's return value is based on realised methods 
and does not take into account
+     * objects or classes that implement invokeMethod or methodMissing
+     *
+     * <p>This method is "safe" in that it will always return a value and 
never throw an exception
+     *
+     * @param obj The object to inspect
+     * @param name The name of the method of interest
+     * @return A List of MetaMethods which will be empty if no methods with 
the given name exist
+     */
+    List<MetaMethod> respondsTo(Object obj, String name);
+
+    /**
+     * <p>Returns true of the implementing MetaClass has a property of the 
given name
+     *
+     * <p>Note that this method will only return true for realised properties 
and does not take into
+     * account implementation of getProperty or propertyMissing
+     *
+     * @param obj The object to inspect
+     * @param name The name of the property
+     * @return The MetaProperty or null if it doesn't exist
+     */
+    MetaProperty hasProperty(Object obj, String name);
+
+    /**
+     * Returns a MetaProperty for the given name or null if it doesn't exist
+     *
+     * @param name The name of the MetaProperty
+     * @return A MetaProperty or null
+     */
+    MetaProperty getMetaProperty(String name);
+
+    /**
+     * Retrieves a static MetaMethod for the given name and argument values, 
using the types of the arguments
+     * to establish the chosen MetaMethod
+     *
+     * @param name The name of the MetaMethod
+     * @param args The argument types
+     * @return A MetaMethod or null if it doesn't exist
+     */
+    MetaMethod getStaticMetaMethod(String name, Object[] args);
+
+
+    /**
+     * Retrieves an instance MetaMethod for the given name and argument 
values, using the types of the
+     * argument values to establish the chosen MetaMethod
+     *
+     * @param name The name of the MetaMethod
+     * @param args Array containing - 1) the argument values (using which 
their types are then inferred), or 2) the corresponding argument types  
+     * @return A MetaMethod or null if it doesn't exist
+     */
+    MetaMethod getMetaMethod(String name, Object[] args);
+
+    /**
+     * Retrieves that Java Class that the attached Meta behaviours apply to
+     *
+     * @return The java.lang.Class instance
+     */
+    Class getTheClass();
+
+    /**
+     * Invokes a constructor for the given arguments. The MetaClass will 
attempt to pick the best argument which
+     * matches the types of the objects passed within the arguments array
+     *
+     * @param arguments The arguments to the constructor
+     * @return An instance of the java.lang.Class that this MetaObjectProtocol 
object applies to
+     */
+    Object invokeConstructor(Object[] arguments);
+
+    /**
+     * Invokes a method on the given Object with the given name and arguments. 
The MetaClass will attempt to pick
+     * the best method for the given name and arguments. If a method cannot be 
invoked a MissingMethodException will be
+     * thrown.
+     *
+     * @see groovy.lang.MissingMethodException
+     * @param object The instance which the method is invoked on
+     * @param methodName The name of the method
+     * @param arguments The arguments to the method
+     * @return The return value of the method which is null if the return type 
is void
+     */
+    Object invokeMethod(Object object, String methodName, Object[] arguments);
+
+    /**
+     * Invokes a method on the given object, with the given name and single 
argument.
+     *
+     * @see #invokeMethod(Object, String, Object[])
+     * @param object The Object to invoke the method on
+     * @param methodName The name of the method
+     * @param arguments The argument to the method
+     * @return The return value of the method which is null if the return type 
is void
+     */
+     Object invokeMethod(Object object, String methodName, Object arguments);
+
+    /**
+     * Invokes a static method on the given Object with the given name and 
arguments.
+     * <p>
+     * The Object can either be an instance of the class that this
+     * MetaObjectProtocol instance applies to or the java.lang.Class instance 
itself. If a method cannot be invoked
+     * a MissingMethodException is will be thrown
+     *
+     * @see groovy.lang.MissingMethodException
+     * @param object An instance of the class returned by the getTheClass() 
method or the class itself
+     * @param methodName The name of the method
+     * @param arguments The arguments to the method
+     * @return The return value of the method which is null if the return type 
is void
+     */
+    Object invokeStaticMethod(Object object, String methodName, Object[] 
arguments);
+
+    /**
+     * Retrieves a property of an instance of the class returned by the 
getTheClass() method.
+     * <p>
+     * What this means is largely down to the MetaClass implementation, 
however the default case would result
+     * in an attempt to invoke a JavaBean getter, or if no such getter exists 
a public field of the instance.
+     *
+     * @see MetaClassImpl
+     * @param object An instance of the class returned by the getTheClass() 
method
+     * @param property The name of the property to retrieve the value for
+     * @return The properties value
+     */
+    Object getProperty(Object object, String property);
+
+    /**
+     * Sets a property of an instance of the class returned by the 
getTheClass() method.
+     * <p>
+     * What this means is largely down to the MetaClass implementation, 
however the default case would result
+     * in an attempt to invoke a JavaBean setter, or if no such setter exists 
to set a public field of the instance.
+     *
+     * @see MetaClassImpl
+     * @param object An instance of the class returned by the getTheClass() 
method
+     * @param property The name of the property to set
+     * @param newValue The new value of the property
+     */
+    void setProperty(Object object, String property, Object newValue);
+
+    /**
+     * Retrieves an attribute of an instance of the class returned by the 
getTheClass() method.
+     * <p>
+     * What this means is largely down to the MetaClass implementation, 
however the default case would result
+     * in attempt to read a field of the instance.
+     *
+     * @see MetaClassImpl
+     * @param object An instance of the class returned by the getTheClass() 
method
+     * @param attribute The name of the attribute to retrieve the value for
+     * @return The attribute value
+     */
+    Object getAttribute(Object object, String attribute);
+
+    /**
+     * Sets an attribute of an instance of the class returned by the 
getTheClass() method.
+     * <p>
+     * What this means is largely down to the MetaClass implementation, 
however the default case would result
+     * in an attempt to set a field of the instance.
+     *
+     * @see MetaClassImpl
+     * @param object An instance of the class returned by the getTheClass() 
method
+     * @param attribute The name of the attribute to set
+     * @param newValue The new value of the attribute
+     */
+    void setAttribute(Object object, String attribute, Object newValue);
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/groovy/lang/MetaProperty.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/MetaProperty.java 
b/src/main/groovy/groovy/lang/MetaProperty.java
new file mode 100644
index 0000000..d3c9633
--- /dev/null
+++ b/src/main/groovy/groovy/lang/MetaProperty.java
@@ -0,0 +1,102 @@
+/*
+ *  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.codehaus.groovy.runtime.MetaClassHelper;
+
+import java.lang.reflect.Modifier;
+
+/**
+ * Represents a property on a bean which may have a getter and/or a setter
+ * 
+ * @author <a href="mailto:[email protected]";>James Strachan</a>
+ */
+public abstract class MetaProperty {
+
+    protected final String name;
+    protected Class type;
+    public static final String PROPERTY_SET_PREFIX = "set";
+
+    /**
+     * Constructor that sets the property name and type (class)
+     */
+    public MetaProperty(String name, Class type) {
+        this.name = name;
+        this.type = type;
+    }
+
+    /**
+     * @return the property of the given object
+     * @throws Exception if the property could not be evaluated
+     */
+    public abstract Object getProperty(Object object);
+
+    /**
+     * Sets the property on the given object to the new value
+     * 
+     * @param object on which to set the property
+     * @param newValue the new value of the property
+     * @throws RuntimeException if the property could not be set
+     */
+    public abstract void setProperty(Object object, Object newValue);
+
+    /**
+     * Return the name of the property
+     *
+     * @return the name of the property
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * @return the type of the property
+     */
+    public Class getType() {
+        return type;
+    }
+    
+    /**
+     * Returns the access modifier.
+     * @return Modifier.PUBLIC
+     */
+    public int getModifiers() {
+        return Modifier.PUBLIC;
+    }
+
+    /**
+     * Gets the name for the getter for this property
+     *
+     * @return The name of the property. The name is "get"+ the capitalized 
propertyName
+     *         or, in the case of boolean values, "is" + the capitalized 
propertyName
+     */
+    public static String getGetterName(String propertyName, Class type) {
+        String prefix = type == boolean.class || type == Boolean.class ? "is" 
: "get";
+        return prefix + MetaClassHelper.capitalize(propertyName);
+    }
+
+    /**
+     * Gets the setter for the getter for this property.
+     *
+     * @return The name of the property. The name is "set"+ the capitalized 
propertyName.
+     */
+    public static String getSetterName(String propertyName) {
+        return PROPERTY_SET_PREFIX + MetaClassHelper.capitalize(propertyName);
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/groovy/lang/MissingClassException.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/MissingClassException.java 
b/src/main/groovy/groovy/lang/MissingClassException.java
new file mode 100644
index 0000000..ad8e5f5
--- /dev/null
+++ b/src/main/groovy/groovy/lang/MissingClassException.java
@@ -0,0 +1,53 @@
+/*
+ *  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.codehaus.groovy.ast.ASTNode;
+import org.codehaus.groovy.ast.ClassNode;
+
+/**
+ * An exception occurred if a dynamic method dispatch fails with an unknown 
class.
+ * 
+ * Note that the Missing*Exception classes were named for consistency and
+ * to avoid conflicts with JDK exceptions of the same name.
+ * 
+ * @author <a href="mailto:[email protected]";>James Strachan</a>
+ */
+public class MissingClassException extends GroovyRuntimeException {
+
+    private final String type;
+
+    public MissingClassException(String type, ASTNode node, String message) {
+        super("No such class: " + type + " " + message, node);
+        this.type = type;
+    }
+    
+    public MissingClassException(ClassNode type, String message){
+        super("No such class: " + type.getName() + " " + message);
+        this.type = type.getName();
+    }
+
+    /**
+     * 
+     * @return The type that could not be resolved
+     */
+    public String getType() {
+        return type;
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/groovy/lang/MissingFieldException.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/MissingFieldException.java 
b/src/main/groovy/groovy/lang/MissingFieldException.java
new file mode 100644
index 0000000..3c17d39
--- /dev/null
+++ b/src/main/groovy/groovy/lang/MissingFieldException.java
@@ -0,0 +1,67 @@
+/*
+ *  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;
+
+
+/**
+ * An exception occurred if a dynamic field dispatch fails with an unknown 
field.
+ * 
+ * Note that the Missing*Exception classes were named for consistency and
+ * to avoid conflicts with JDK exceptions of the same name.
+ * 
+ * @author <a href="mailto:[email protected]";>James Strachan</a>
+ */
+public class MissingFieldException extends GroovyRuntimeException {
+
+    private final String field;
+    private final Class type;
+
+    public MissingFieldException(String field, Class type) {
+        super("No such field: " + field + " for class: " + type.getName());
+        this.field = field;
+        this.type = type;
+    }
+
+    public MissingFieldException(String field, Class type, Throwable e) {
+        super("No such field: " + field + " for class: " + type.getName() + ". 
Reason: " + e, e);
+        this.field = field;
+        this.type = type;
+    }
+
+    public MissingFieldException(String message, String field, Class type) {
+        super(message);
+        this.field = field;
+        this.type = type;
+    }
+
+    /**
+     * @return the name of the field that could not be found
+     */
+    public String getField() {
+        return field;
+    }
+
+    /**
+     * 
+     * @return The type on which the field was attempted to be called
+     */
+    public Class getType() {
+        return type;
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/groovy/lang/MissingMethodException.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/MissingMethodException.java 
b/src/main/groovy/groovy/lang/MissingMethodException.java
new file mode 100644
index 0000000..0902150
--- /dev/null
+++ b/src/main/groovy/groovy/lang/MissingMethodException.java
@@ -0,0 +1,88 @@
+/*
+ *  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.codehaus.groovy.runtime.InvokerHelper;
+import org.codehaus.groovy.runtime.MethodRankHelper;
+
+/**
+ * An exception occurred if a dynamic method dispatch fails with an unknown 
method.
+ * <p>
+ * Note that the Missing*Exception classes were named for consistency and
+ * to avoid conflicts with JDK exceptions of the same name.
+ */
+public class MissingMethodException extends GroovyRuntimeException {
+
+    private final String method;
+    private final Class type;
+    private final boolean isStatic;
+
+    public Object[] getArguments() {
+        return arguments;
+    }
+
+    private final Object arguments[];
+
+    public MissingMethodException(String method, Class type, Object[] 
arguments) {
+        this(method, type, arguments, false);
+    }
+
+    public MissingMethodException(String method, Class type, Object[] 
arguments, boolean isStatic) {
+        super();
+        this.method = method;
+        this.type = type;
+        this.isStatic = isStatic;
+        this.arguments = arguments;
+    }
+
+    public String getMessage() {
+        return "No signature of method: "
+                + (isStatic ? "static " : "")
+                + type.getName()
+                + "."
+                + method
+                + "() is applicable for argument types: ("
+                + InvokerHelper.toTypeString(arguments, 60)
+                + ") values: "
+                + InvokerHelper.toArrayString(arguments, 60, true)
+                + MethodRankHelper.getMethodSuggestionString(method, type, 
arguments);
+    }
+
+    /**
+     * @return the name of the method that could not be found
+     */
+    public String getMethod() {
+        return method;
+    }
+
+    /**
+     * @return The type on which the method was attempted to be called
+     */
+    public Class getType() {
+        return type;
+    }
+
+    /**
+     * @return Whether the method was called in a static way,
+     *         i.e. on a class rather than an object.
+     */
+    public boolean isStatic() {
+        return isStatic;
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/groovy/lang/MissingPropertyException.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/MissingPropertyException.java 
b/src/main/groovy/groovy/lang/MissingPropertyException.java
new file mode 100644
index 0000000..270f039
--- /dev/null
+++ b/src/main/groovy/groovy/lang/MissingPropertyException.java
@@ -0,0 +1,88 @@
+/*
+ *  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.codehaus.groovy.runtime.MethodRankHelper;
+
+
+/**
+ * An exception occurred if a dynamic property dispatch fails with an unknown 
property.
+ * 
+ * Note that the Missing*Exception classes were named for consistency and
+ * to avoid conflicts with JDK exceptions of the same name.
+ * 
+ * @author <a href="mailto:[email protected]";>James Strachan</a>
+ */
+public class MissingPropertyException extends GroovyRuntimeException {
+
+    public static final Object MPE = new Object();
+
+    private final String property;
+    private final Class type;
+
+    public MissingPropertyException(String property, Class type) {
+        this.property = property;
+        this.type = type;
+    }
+
+    public MissingPropertyException(String property, Class type, Throwable t) {
+        super(t);
+        this.property = property;
+        this.type = type;
+    }
+
+    public MissingPropertyException(String message) {
+        super(message);
+        this.property = null;
+        this.type = null;
+    }
+
+    public MissingPropertyException(String message, String property, Class 
type) {
+        super(message);
+        this.property = property;
+        this.type = type;
+    }
+
+    public String getMessageWithoutLocationText() {
+        final Throwable cause = getCause();
+        if (cause == null) {
+            if (super.getMessageWithoutLocationText() != null) {
+                return super.getMessageWithoutLocationText();
+            }
+            return "No such property: " + property + " for class: " + 
type.getName() +
+                   MethodRankHelper.getPropertySuggestionString(property, 
type);
+        }
+        return "No such property: " + property + " for class: " + 
type.getName() + ". Reason: " + cause;
+    }
+
+    /**
+     * @return the name of the property that could not be found
+     */
+    public String getProperty() {
+        return property;
+    }
+
+    /**
+     * 
+     * @return The type on which the property was attempted to be called
+     */
+    public Class getType() {
+        return type;
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/groovy/lang/Mixin.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/Mixin.java 
b/src/main/groovy/groovy/lang/Mixin.java
new file mode 100644
index 0000000..22ef4b9
--- /dev/null
+++ b/src/main/groovy/groovy/lang/Mixin.java
@@ -0,0 +1,42 @@
+/*
+ *  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.codehaus.groovy.transform.GroovyASTTransformationClass;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Provides a mechanism for mixing in methods into a class.
+ *
+ * @deprecated static mixins have been deprecated in favour of traits (trait 
keyword).
+ *
+ * @author Alex Tkachman
+ */
[email protected]
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+@GroovyASTTransformationClass("org.codehaus.groovy.ast.MixinASTTransformation")
+@Deprecated
+public @interface Mixin {
+    Class [] value ();
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/groovy/lang/MutableMetaClass.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/MutableMetaClass.java 
b/src/main/groovy/groovy/lang/MutableMetaClass.java
new file mode 100644
index 0000000..903c895
--- /dev/null
+++ b/src/main/groovy/groovy/lang/MutableMetaClass.java
@@ -0,0 +1,79 @@
+/*
+ *  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 java.lang.reflect.Method;
+
+/**
+ * An interface that defines methods that implementers of mutable Meta classes 
should specify. It provides operations to perform mutations
+ * on the MetaClass instance.
+ * <p>
+ * Whether a MetaClass allows mutation is up to the MetaClass itself and 
considerations of Thread safety
+ * need to be taken into account when making a MetaClass mutable
+ * <p>
+ * The default implementation allows mutation of MetaClass instances before 
initialisation (before the initialize() method is called)
+ * but not after, thus ensuring Thread safety once a MetaClass has been 
constructed and placed in the registry
+ *
+ * @see MetaClassImpl
+ * @see MetaClass
+ * @author Graeme Rocher
+ * @since 1.5
+ */
+public interface MutableMetaClass extends MetaClass {
+
+    /**
+     * Return whether the MetaClass has been modified or not
+     * @return True if it has
+     */
+    boolean isModified();
+
+    /**
+     * adds a new instance method to this MetaClass. Instance
+     * methods are able to overwrite the original methods of the
+     * class. Calling this method should not be done after
+     * initialise was called.
+     *
+     * @param method the method to be added
+     */
+     void addNewInstanceMethod(Method method);
+
+    /**
+     * adds a new static method to this MetaClass. This is only
+     * possible as long as initialise was not called.
+     *
+     * @param method the method to be added
+     */
+     void addNewStaticMethod(Method method);
+
+    /**
+     * Adds a new MetaMethod to the MetaClass
+     *
+     * @param metaMethod The MetaMethod to add
+     */
+    void addMetaMethod(MetaMethod metaMethod);
+
+    /**
+     * Adds a new MetaBeanProperty to the MetaClass
+     *
+     * @param metaBeanProperty The MetaBeanProperty instance
+     */
+    void addMetaBeanProperty(MetaBeanProperty metaBeanProperty);
+    
+    // TODO: Add methods like addMetaConstructor, addMetaAttribute, 
addMetaAnnotation etc.
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/groovy/lang/Newify.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/Newify.java 
b/src/main/groovy/groovy/lang/Newify.java
new file mode 100644
index 0000000..525cecb
--- /dev/null
+++ b/src/main/groovy/groovy/lang/Newify.java
@@ -0,0 +1,109 @@
+/*
+ *  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.codehaus.groovy.transform.GroovyASTTransformationClass;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation that supports writing constructor call expressions without the 
'new'
+ * keyword. Instead they can be written "Ruby-style" as a method call to a 
'new'
+ * method or "Python-style" by just omitting the 'new' keyword.
+ * <p>
+ * It allows you to write code snippets like this ("Python-style"):
+ * <pre>
+ * {@code @Newify([Tree,Leaf])} class MyTreeProcessor {
+ *     def myTree = Tree(Tree(Leaf("A"), Leaf("B")), Leaf("C"))
+ *     def process() { ... }
+ * }
+ * </pre>
+ * or this ("Ruby-style"):
+ * <pre>
+ * {@code @Newify} class MyTreeProcessor {
+ *     def myTree = Tree.new(Tree.new(Leaf.new("A"), Leaf.new("B")), 
Leaf.new("C"))
+ *     def process() { ... }
+ * }
+ * </pre>
+ *
+ * After the AST transformation, the following code is passed on for further 
compilation:
+ * <pre>
+ * class MyTreeProcessor {
+ *     def myTree = new Tree(new Tree(new Leaf("A"), new Leaf("B")), new 
Leaf("C"))
+ *     def process() { ... }
+ * }
+ * </pre>
+ * The annotation can be used on a whole class as shown above or selectively 
on a particular
+ * method, constructor or field.
+ * <p>
+ * The "Ruby-style" new conversions occur automatically unless the 'auto=false'
+ * flag is given when using the annotation. You might do this if you create a 
new method
+ * using meta programming.
+ * <p>
+ * The "Python-style" conversions require you to specify each class on which 
you want them
+ * to apply. The transformation then works by matching the basename of the 
provided classes to any
+ * similarly named instance method calls not specifically bound to an object, 
i.e. associated
+ * with the 'this' object. In other words <code>Leaf("A")</code> would be 
transformed to
+ * <code>new Leaf("A")</code> but <code>x.Leaf("A")</code> would not be 
touched.
+ * <p>
+ * An example showing how to use the annotation at different levels:
+ * <pre>
+ * {@code @Newify(auto=false, value=Foo)}
+ * class Main {
+ *     {@code @Newify} // turn auto on for field
+ *     def field1 = java.math.BigInteger.new(42)
+ *     def field2, field3, field4
+ *
+ *     {@code @Newify(Bar)}
+ *     def process() {
+ *         field2 = Bar("my bar")
+ *     }
+ *
+ *     {@code @Newify(Baz)}
+ *     Main() {
+ *         field3 = Foo("my foo")
+ *         field4 = Baz("my baz")
+ *     }
+ * }
+ * </pre>
+ *
+ * The annotation is intended to be used sparingly; perhaps in DSL scenarios 
or when
+ * using deeply nested structural types. In particular, there is no support 
for using
+ * the facility with two similarly named classes from different packages at 
the same time.
+ * Though it is OK to have different packages in different contexts. Also, 
there is
+ * no support for turning "Ruby-style" conversions off at the method, 
constructor or
+ * field level if already turned on at the class level.
+ *
+ * @author Paul King
+ */
[email protected]
+@Retention(RetentionPolicy.SOURCE)
+@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.TYPE, 
ElementType.FIELD, ElementType.LOCAL_VARIABLE})
+@GroovyASTTransformationClass("org.codehaus.groovy.transform.NewifyASTTransformation")
+public @interface Newify {
+    Class<?>[] value() default {};
+
+    /**
+     * @return if automatic conversion of "Ruby-style" new method calls should 
occur
+     */
+    boolean auto() default true;
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/groovy/lang/NonEmptySequence.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/lang/NonEmptySequence.java 
b/src/main/groovy/groovy/lang/NonEmptySequence.java
new file mode 100644
index 0000000..f069b7a
--- /dev/null
+++ b/src/main/groovy/groovy/lang/NonEmptySequence.java
@@ -0,0 +1,47 @@
+/*
+ *  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 java.util.List;
+
+/**
+ * Represents a sequence of objects which represents one or many instances of
+ * of objects of a given type. The type can be omitted in which case any type 
of
+ * object can be added.
+ *
+ * @author <a href="mailto:[email protected]";>James Strachan</a>
+ */
+public class NonEmptySequence extends Sequence {
+
+    public NonEmptySequence() {
+        super(null);
+    }
+
+    public NonEmptySequence(Class type) {
+        super(type);
+    }
+
+    public NonEmptySequence(Class type, List content) {
+        super(type, content);
+    }
+
+    public int minimumSize() {
+        return 1;
+    }
+}
\ No newline at end of file

Reply via email to