groovy.lang

## Class ExpandoMetaClass

- java.lang.Object
- - groovy.lang.MetaClassImpl
  - - groovy.lang.ExpandoMetaClass

- All Implemented Interfaces:
    GroovyObject, MetaClass, MetaObjectProtocol, MutableMetaClass

      public class ExpandoMetaClass
      extends MetaClassImpl
      implements GroovyObject

  ExpandoMetaClass is a MetaClass that behaves like an Expando, allowing the addition or replacement of methods, properties and constructors on the fly.

  Some examples of usage:

       // defines or replaces instance method:
       metaClass.myMethod = { args -> }

       // defines a new instance method
       metaClass.myMethod << { args -> }

       // creates multiple overloaded methods of the same name
       metaClass.myMethod << { String s -> } << { Integer i -> }

       // defines or replaces a static method with the 'static' qualifier
       metaClass.'static'.myMethod = { args ->  }

       // defines a new static method with the 'static' qualifier
       metaClass.'static'.myMethod << { args ->  }

       // defines a new constructor
       metaClass.constructor << { String arg -> }

       // defines or replaces a constructor
       metaClass.constructor = { String arg -> }

       // defines a new property with an initial value of "blah"
       metaClass.myProperty = "blah"

  ExpandoMetaClass also supports a DSL/builder like notation to combine multiple definitions together. So instead of this:

       Number.metaClass.multiply = { Amount amount -> amount.times(delegate) }
       Number.metaClass.div =      { Amount amount -> amount.inverse().times(delegate) }

  You can also now do this:

       Number.metaClass {
           multiply { Amount amount -> amount.times(delegate) }
           div      { Amount amount -> amount.inverse().times(delegate) }
       }

  ExpandoMetaClass also supports runtime mixins. While `@Mixin` allows you to mix in new behavior to classes you own and are designing, you can not easily mixin anything to types you didn't own, e.g. from third party libraries or from JDK library classes. Runtime mixins let you add a mixin on any type at runtime.

       interface Vehicle {
           String getName()
       }

       // Category annotation style
       @Category(Vehicle) class FlyingAbility {
           def fly() { "I'm the ${name} and I fly!" }
       }

       // traditional category style
       class DivingAbility {
           static dive(Vehicle self) { "I'm the ${self.name} and I dive!" }
       }

       // provided by a third-party, so can't augment using Mixin annotation
       class JamesBondVehicle implements Vehicle {
           String getName() { "James Bond's vehicle" }
       }

       // Can be added via metaClass, e.g.:
       // JamesBondVehicle.metaClass.mixin DivingAbility, FlyingAbility
       // Or using shorthand through DGM method on Class
       JamesBondVehicle.mixin DivingAbility, FlyingAbility

       assert new JamesBondVehicle().fly() ==
              "I'm the James Bond's vehicle and I fly!"
       assert new JamesBondVehicle().dive() ==
              "I'm the James Bond's vehicle and I dive!"

  As another example, consider the following class definitions:

       class Student {
           List schedule = []
           def addLecture(String lecture) { schedule << lecture }
       }

       class Worker {
           List schedule = []
           def addMeeting(String meeting) { schedule << meeting }
       }

  We can mimic a form of multiple inheritance as follows:

       class CollegeStudent {
           static { mixin Student, Worker }
       }
       new CollegeStudent().with {
           addMeeting('Performance review with Boss')
           addLecture('Learn about Groovy Mixins')
           println schedule
           println mixedIn[Student].schedule
           println mixedIn[Worker].schedule
       }

  Which outputs these lines when run:

       [Performance review with Boss]
       [Learn about Groovy Mixins]
       [Performance review with Boss]

  Perhaps some explanation is required here. The methods and properties of Student and Worker are added to CollegeStudent. Worker is added last, so for overlapping methods, its methods will be used, e.g. when calling `schedule`, it will be the schedule property (getSchedule method) from Worker that is used. The schedule property from Student will be shadowed but the `mixedIn` notation allows us to get to that too if we need as the last two lines show.

  We can also be a little more dynamic and not require the CollegeStudent class to be defined at all, e.g.:

       def cs = new Object()
       cs.metaClass {
           mixin Student, Worker
           getSchedule {
               mixedIn[Student].schedule + mixedIn[Worker].schedule
           }
       }
       cs.with {
           addMeeting('Performance review with Boss')
           addLecture('Learn about Groovy Mixins')
           println schedule
       }

  Which outputs this line when run:

       [Learn about Groovy Mixins, Performance review with Boss]

  As another example, we can also define a no dup queue by mixing in some Queue and Set functionality as follows:

       def ndq = new Object()
       ndq.metaClass {
           mixin ArrayDeque
           mixin HashSet
           leftShift = { Object o ->
               if (!mixedIn[Set].contains(o)) {
                   mixedIn[Queue].push(o)
                   mixedIn[Set].add(o)
               }
           }
       }
       ndq << 1
       ndq << 2
       ndq << 1
       assert ndq.size() == 2

  As a final example, we sometimes need to pass such mixed in classes or objects into Java methods which require a given static type but the ExpandoMetaClass mixin approach uses a very dynamic approach based on duck typing rather than static interface definitions, so doesn't by default produce objects matching the required static type. Luckily, there is a mixins capability within ExpandoMetaClass which supports the use of Groovy's common 'as StaticType' notation to produce an object having the correct static type so that it can be passed to the Java method call in question. A slightly contrived example illustrating this feature:

       class CustomComparator implements Comparator {
           int compare(Object a, b) { return a.size() - b.size() }
       }

       class CustomCloseable implements Closeable {
           void close() { println 'Lights out - I am closing' }
       }

       import static mypackage.IOUtils.closeQuietly
       import static java.util.Collections.sort
       def o = new Object()
       o.metaClass.mixin CustomComparator, CustomCloseable
       def items = ['a', 'bbb', 'cc']
       sort(items, o as Comparator)
       println items                // => [a, cc, bbb]
       closeQuietly(o as Closeable) // => Lights out - I am closing

  Further details

  When using the default implementations of MetaClass, methods are only allowed to be added before initialize() is called. In other words you create a new MetaClass, add some methods and then call initialize(). If you attempt to add new methods after initialize() has been called, an error will be thrown. This is to ensure that the MetaClass can operate appropriately in multi-threaded environments as it forces you to do all method additions at the beginning, before using the MetaClass.

  ExpandoMetaClass differs here from the default in that it allows you to add methods after initialize has been called. This is done by setting the initialize flag internally to false and then add the methods. Since this is not thread safe it has to be done in a synchronized block. The methods to check for modification and initialization are therefore synchronized as well. Any method call done through this meta class will first check if the it is synchronized. Should this happen during a modification, then the method cannot be selected or called unless the modification is completed.

  WARNING: This MetaClass uses a thread-bound ThreadLocal instance to store and retrieve properties. In addition properties stored use soft references so they are both bound by the life of the Thread and by the soft references. The implication here is you should NEVER use dynamic properties if you want their values to stick around for long periods because as soon as the JVM is running low on memory or the thread dies they will be garbage collected.
  Since:
    1.5
  Author:
    Graeme Rocher

- - ### Nested Class Summary

    Nested Classes
    Modifier and Type | Class and Description
    --- | ---
    `protected class` | `ExpandoMetaClass.ExpandoMetaConstructor` Handles the ability to use the left shift operator to append new constructors
    `protected class` | `ExpandoMetaClass.ExpandoMetaProperty` Instances of this class are returned when using the << left shift operator.

    - ### Nested classes/interfaces inherited from class groovy.lang.MetaClassImpl

      `MetaClassImpl.Index`

  - ### Field Summary

    Fields
    Modifier and Type | Field and Description
    --- | ---
    `static String` | `CONSTRUCTOR`
    `boolean` | `inRegistry`
    `static String` | `STATIC_QUALIFIER`

    - ### Fields inherited from class groovy.lang.MetaClassImpl

      `getPropertyMethod, INVOKE_METHOD_METHOD, invokeMethodMethod, isGroovyObject, isMap, metaMethodIndex, METHOD_MISSING, PROPERTY_MISSING, registry, setPropertyMethod, STATIC_METHOD_MISSING, STATIC_PROPERTY_MISSING, theCachedClass, theClass`

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `ExpandoMetaClass(Class theClass)` Constructs a new ExpandoMetaClass instance for the given class
    `ExpandoMetaClass(Class theClass, boolean register)` Constructs a new ExpandoMetaClass instance for the given class optionally placing the MetaClass in the MetaClassRegistry automatically
    `ExpandoMetaClass(Class theClass, boolean register, boolean allowChangesAfterInit)` Constructs a new ExpandoMetaClass instance for the given class optionally placing the MetaClass in the MetaClassRegistry automatically
    `ExpandoMetaClass(Class theClass, boolean register, MetaMethod[] add)`
    `ExpandoMetaClass(Class theClass, MetaMethod[] add)`

  - ### Method Summary

    Methods
    Modifier and Type | Method and Description
    --- | ---
    `void` | `addMixinClass(MixinInMetaClass mixin)`
    `Object` | `castToMixedType(Object obj, Class type)`
    `CallSite` | `createConstructorSite(CallSite site, Object[] args)`
    `CallSite` | `createPogoCallCurrentSite(CallSite site, Class sender, String name, Object[] args)`
    `CallSite` | `createPogoCallSite(CallSite site, Object[] args)`
    `CallSite` | `createPojoCallSite(CallSite site, Object receiver, Object[] args)`
    `CallSite` | `createStaticSite(CallSite site, Object[] args)`
    `ExpandoMetaClass` | `define(Closure closure)`
    `static void` | `disableGlobally()` Call to disable the global use of ExpandoMetaClass
    `static void` | `enableGlobally()` Call to enable global use of global use of ExpandoMetaClass within the registry.
    `MetaMethod` | `findMixinMethod(String methodName, Class[] arguments)`
    `List<MetaMethod>` | `getExpandoMethods()` Returns a list of expando MetaMethod instances added to this ExpandoMetaClass
    `Collection<MetaProperty>` | `getExpandoProperties()` Returns a list of MetaBeanProperty instances added to this ExpandoMetaClass
    `Collection` | `getExpandoSubclassMethods()`
    `Class` | `getJavaClass()`
    `MetaClass` | `getMetaClass()` Returns the metaclass for a given class.
    `MetaProperty` | `getMetaProperty(String name)` Looks up an existing MetaProperty by name
    `List<MetaMethod>` | `getMethods()` Overrides the behavior of parent getMethods() method to make MetaClass aware of added Expando methods
    `List<MetaProperty>` | `getProperties()` Get all the properties defined for this type
    `Object` | `getProperty(Class sender, Object object, String name, boolean useSuper, boolean fromInsideClass)` Overrides default implementation just in case getProperty method has been overridden by ExpandoMetaClass
    `Object` | `getProperty(Object object, String name)` Overrides default implementation just in case getProperty method has been overridden by ExpandoMetaClass
    `Object` | `getProperty(String property)` Retrieves a property value.
    `String` | `getPropertyForSetter(String setterName)` Returns a property name equivalent for the given setter name or null if it is not a getter
    `protected Object` | `getSubclassMetaMethods(String methodName)`
    `boolean` | `hasMetaMethod(String name, Class[] args)` Checks whether a MetaMethod for the given name and arguments exists
    `boolean` | `hasMetaProperty(String name)` Returns true if the MetaClass has the given property
    `void` | `initialize()` complete the initialisation process.
    `Object` | `invokeConstructor(Object[] arguments)` Invokes a constructor for the given arguments.
    `Object` | `invokeMethod(Class sender, Object object, String methodName, Object[] originalArguments, boolean isCallToSuper, boolean fromInsideClass)` Overrides default implementation just in case invokeMethod has been overridden by ExpandoMetaClass
    `Object` | `invokeMethod(String name, Object args)` Invokes the given method.
    `Object` | `invokeStaticMethod(Object object, String methodName, Object[] arguments)` Overrides default implementation just in case a static invoke method has been set on ExpandoMetaClass
    `protected boolean` | `isInitialized()` Checks if the meta class is initialized.
    `boolean` | `isModified()` Return whether the MetaClass has been modified or not
    `boolean` | `isSetter(String name, CachedClass[] args)`
    `static boolean` | `isValidExpandoProperty(String property)`
    `protected void` | `onGetPropertyFoundInHierarchy(MetaMethod method)`
    `protected void` | `onInvokeMethodFoundInHierarchy(MetaMethod method)`
    `protected void` | `onSetPropertyFoundInHierarchy(MetaMethod method)`
    `protected void` | `onSuperMethodFoundInHierarchy(MetaMethod method)`
    `protected void` | `onSuperPropertyFoundInHierarchy(MetaBeanProperty property)`
    `protected void` | `performOperationOnMetaClass(groovy.lang.ExpandoMetaClass.Callable c)`
    `void` | `refreshInheritedMethods(Set modifiedSuperExpandos)` Called from ExpandoMetaClassCreationHandle in the registry if it exists to set up inheritance handling
    `void` | `registerBeanProperty(String property, Object newValue)` Registers a new bean property
    `void` | `registerInstanceMethod(MetaMethod metaMethod)` Registers a new instance method for the given method name and closure on this MetaClass
    `void` | `registerInstanceMethod(String name, Closure closure)`
    `protected void` | `registerStaticMethod(String name, Closure callable)`
    `protected void` | `registerStaticMethod(String name, Closure callable, Class[] paramTypes)` Registers a new static method for the given method name and closure on this MetaClass
    `void` | `registerSubclassInstanceMethod(MetaMethod metaMethod)`
    `void` | `registerSubclassInstanceMethod(String name, Class klazz, Closure closure)`
    `protected void` | `setInitialized(boolean b)`
    `void` | `setMetaClass(MetaClass metaClass)` Allows the MetaClass to be replaced with a derived implementation.
    `void` | `setProperty(Class sender, Object object, String name, Object newValue, boolean useSuper, boolean fromInsideClass)` Overrides default implementation just in case setProperty method has been overridden by ExpandoMetaClass
    `void` | `setProperty(String property, Object newValue)` Sets the given property to the new value.

    - ### Methods inherited from class groovy.lang.MetaClassImpl

      `addMetaBeanProperty, addMetaMethod, addMetaMethodToIndex, addNewInstanceMethod, addNewStaticMethod, applyPropertyDescriptors, checkIfGroovyObjectMethod, checkInitalised, chooseMethod, clearInvocationCaches, createPogoCallCurrentSite, dropMethodCache, dropStaticMethodCache, findMethodInClassHierarchy, findOwnMethod, findPropertyInClassHierarchy, getAdditionalMetaMethods, getAttribute, getAttribute, getAttribute, getClassInfo, getClassNode, getEffectiveGetMetaProperty, getMetaMethod, getMetaMethods, getMethodWithCaching, getMethodWithoutCaching, getStaticMetaMethod, getSuperClasses, getTheCachedClass, getTheClass, getVersion, hasProperty, incVersion, invokeConstructorAt, invokeMethod, invokeMethod, invokeMissingMethod, invokeMissingProperty, invokeStaticMissingProperty, isGroovyObject, onMixinMethodFound, pickMethod, respondsTo, respondsTo, retrieveConstructor, retrieveMethod, retrieveStaticMethod, selectConstructorAndTransformArguments, setAttribute, setAttribute, setProperties, setProperty, toString`

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait`

- - ### Field Detail

    - #### STATIC_QUALIFIER

          public static final String STATIC_QUALIFIER

      See Also:
        Constant Field Values

    - #### CONSTRUCTOR

          public static final String CONSTRUCTOR

      See Also:
        Constant Field Values

    - #### inRegistry

          public boolean inRegistry

  - ### Constructor Detail

    - #### ExpandoMetaClass

          public ExpandoMetaClass(Class theClass)

      Constructs a new ExpandoMetaClass instance for the given class
      Parameters:
        `theClass` - The class that the MetaClass applies to

    - #### ExpandoMetaClass

          public ExpandoMetaClass(Class theClass,
                          MetaMethod[] add)

    - #### ExpandoMetaClass

          public ExpandoMetaClass(Class theClass,
                          boolean register)

      Constructs a new ExpandoMetaClass instance for the given class optionally placing the MetaClass in the MetaClassRegistry automatically
      Parameters:
        `theClass` - The class that the MetaClass applies to
        `register` - True if the MetaClass should be registered inside the MetaClassRegistry. This defaults to true and ExpandoMetaClass will effect all instances if changed

    - #### ExpandoMetaClass

          public ExpandoMetaClass(Class theClass,
                          boolean register,
                          MetaMethod[] add)

    - #### ExpandoMetaClass

          public ExpandoMetaClass(Class theClass,
                          boolean register,
                          boolean allowChangesAfterInit)

      Constructs a new ExpandoMetaClass instance for the given class optionally placing the MetaClass in the MetaClassRegistry automatically
      Parameters:
        `theClass` - The class that the MetaClass applies to
        `register` - True if the MetaClass should be registered inside the MetaClassRegistry. This defaults to true and ExpandoMetaClass will effect all instances if changed
        `allowChangesAfterInit` - Should the meta class be modifiable after initialization. Default is false.

  - ### Method Detail

    - #### getExpandoSubclassMethods

          public Collection getExpandoSubclassMethods()

    - #### findMixinMethod

          public MetaMethod findMixinMethod(String methodName,
                                   Class[] arguments)

      Overrides:
        `findMixinMethod` in class `MetaClassImpl`

    - #### onInvokeMethodFoundInHierarchy

          protected void onInvokeMethodFoundInHierarchy(MetaMethod method)

      Overrides:
        `onInvokeMethodFoundInHierarchy` in class `MetaClassImpl`

    - #### onSuperMethodFoundInHierarchy

          protected void onSuperMethodFoundInHierarchy(MetaMethod method)

      Overrides:
        `onSuperMethodFoundInHierarchy` in class `MetaClassImpl`

    - #### onSuperPropertyFoundInHierarchy

          protected void onSuperPropertyFoundInHierarchy(MetaBeanProperty property)

      Overrides:
        `onSuperPropertyFoundInHierarchy` in class `MetaClassImpl`

    - #### onSetPropertyFoundInHierarchy

          protected void onSetPropertyFoundInHierarchy(MetaMethod method)

      Overrides:
        `onSetPropertyFoundInHierarchy` in class `MetaClassImpl`

    - #### onGetPropertyFoundInHierarchy

          protected void onGetPropertyFoundInHierarchy(MetaMethod method)

      Overrides:
        `onGetPropertyFoundInHierarchy` in class `MetaClassImpl`

    - #### isModified

          public boolean isModified()

      Description copied from interface: `MutableMetaClass`
      Return whether the MetaClass has been modified or not
      Specified by:
        `isModified` in interface `MutableMetaClass`
      Overrides:
        `isModified` in class `MetaClassImpl`
      Returns:
        True if it has

    - #### registerSubclassInstanceMethod

          public void registerSubclassInstanceMethod(String name,
                                            Class klazz,
                                            Closure closure)

    - #### registerSubclassInstanceMethod

          public void registerSubclassInstanceMethod(MetaMethod metaMethod)

    - #### addMixinClass

          public void addMixinClass(MixinInMetaClass mixin)

    - #### castToMixedType

          public Object castToMixedType(Object obj,
                               Class type)

    - #### enableGlobally

          public static void enableGlobally()

      Call to enable global use of global use of ExpandoMetaClass within the registry. This has the advantage that inheritance will function correctly, but has a higher memory usage on the JVM than normal Groovy

    - #### disableGlobally

          public static void disableGlobally()

      Call to disable the global use of ExpandoMetaClass

    - #### initialize

          public void initialize()

      Description copied from interface: `MetaClass`
      complete the initialisation process. After this method is called no methods should be added to the meta class. Invocation of methods or access to fields/properties is forbidden unless this method is called. This method should contain any initialisation code, taking a longer time to complete. An example is the creation of the Reflector. It is suggested to synchronize this method.
      Specified by:
        `initialize` in interface `MetaClass`
      Overrides:
        `initialize` in class `MetaClassImpl`

    - #### isInitialized

          protected boolean isInitialized()

      Checks if the meta class is initialized.
      Overrides:
        `isInitialized` in class `MetaClassImpl`
      See Also:
        `MetaClassImpl.isInitialized()`

    - #### setInitialized

          protected void setInitialized(boolean b)

    - #### invokeConstructor

          public Object invokeConstructor(Object[] arguments)

      Description copied from interface: `MetaObjectProtocol`
      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
      Specified by:
        `invokeConstructor` in interface `MetaObjectProtocol`
      Overrides:
        `invokeConstructor` in class `MetaClassImpl`
      Parameters:
        `arguments` - The arguments to the constructor
      Returns:
        An instance of the java.lang.Class that this MetaObjectProtocol object applies to

    - #### getMetaClass

          public MetaClass getMetaClass()

      Description copied from interface: `GroovyObject`
      Returns the metaclass for a given class.
      Specified by:
        `getMetaClass` in interface `GroovyObject`
      Returns:
        the metaClass of this instance

    - #### getProperty

          public Object getProperty(String property)

      Description copied from interface: `GroovyObject`
      Retrieves a property value.
      Specified by:
        `getProperty` in interface `GroovyObject`
      Parameters:
        `property` - the name of the property of interest
      Returns:
        the given property

    - #### isValidExpandoProperty

          public static boolean isValidExpandoProperty(String property)

    - #### invokeMethod

          public Object invokeMethod(String name,
                            Object args)

      Description copied from interface: `GroovyObject`
      Invokes the given method.
      Specified by:
        `invokeMethod` in interface `GroovyObject`
      Parameters:
        `name` - the name of the method to call
        `args` - the arguments to use for the method call
      Returns:
        the result of invoking the method

    - #### setMetaClass

          public void setMetaClass(MetaClass metaClass)

      Description copied from interface: `GroovyObject`
      Allows the MetaClass to be replaced with a derived implementation.
      Specified by:
        `setMetaClass` in interface `GroovyObject`
      Parameters:
        `metaClass` - the new metaclass

    - #### setProperty

          public void setProperty(String property,
                         Object newValue)

      Description copied from interface: `GroovyObject`
      Sets the given property to the new value.
      Specified by:
        `setProperty` in interface `GroovyObject`
      Parameters:
        `property` - the name of the property of interest
        `newValue` - the new value for the property

    - #### define

          public ExpandoMetaClass define(Closure closure)

    - #### performOperationOnMetaClass

          protected void performOperationOnMetaClass(groovy.lang.ExpandoMetaClass.Callable c)

    - #### registerBeanProperty

          public void registerBeanProperty(String property,
                                  Object newValue)

      Registers a new bean property
      Parameters:
        `property` - The property name
        `newValue` - The properties initial value

    - #### registerInstanceMethod

          public void registerInstanceMethod(MetaMethod metaMethod)

      Registers a new instance method for the given method name and closure on this MetaClass
      Parameters:
        `metaMethod` -

    - #### registerInstanceMethod

          public void registerInstanceMethod(String name,
                                    Closure closure)

    - #### getMethods

          public List<MetaMethod> getMethods()

      Overrides the behavior of parent getMethods() method to make MetaClass aware of added Expando methods
      Specified by:
        `getMethods` in interface `MetaClass`
      Specified by:
        `getMethods` in interface `MetaObjectProtocol`
      Overrides:
        `getMethods` in class `MetaClassImpl`
      Returns:
        A list of MetaMethods
      See Also:
        `MetaObjectProtocol.getMethods()`

    - #### getProperties

          public List<MetaProperty> getProperties()

      Description copied from class: `MetaClassImpl`
      Get all the properties defined for this type
      Specified by:
        `getProperties` in interface `MetaClass`
      Specified by:
        `getProperties` in interface `MetaObjectProtocol`
      Overrides:
        `getProperties` in class `MetaClassImpl`
      Returns:
        a list of MetaProperty objects
      See Also:
        `MetaProperty`

    - #### registerStaticMethod

          protected void registerStaticMethod(String name,
                                  Closure callable)

    - #### registerStaticMethod

          protected void registerStaticMethod(String name,
                                  Closure callable,
                                  Class[] paramTypes)

      Registers a new static method for the given method name and closure on this MetaClass
      Parameters:
        `name` - The method name
        `callable` - The callable Closure

    - #### getSubclassMetaMethods

          protected Object getSubclassMetaMethods(String methodName)

      Overrides:
        `getSubclassMetaMethods` in class `MetaClassImpl`

    - #### getJavaClass

          public Class getJavaClass()

      Returns:
        The Java class enhanced by this MetaClass

    - #### refreshInheritedMethods

          public void refreshInheritedMethods(Set modifiedSuperExpandos)

      Called from ExpandoMetaClassCreationHandle in the registry if it exists to set up inheritance handling
      Parameters:
        `modifiedSuperExpandos` - A list of modified super ExpandoMetaClass

    - #### getExpandoMethods

          public List<MetaMethod> getExpandoMethods()

      Returns a list of expando MetaMethod instances added to this ExpandoMetaClass
      Returns:
        the expandoMethods

    - #### getExpandoProperties

          public Collection<MetaProperty> getExpandoProperties()

      Returns a list of MetaBeanProperty instances added to this ExpandoMetaClass
      Returns:
        the expandoProperties

    - #### invokeMethod

          public Object invokeMethod(Class sender,
                            Object object,
                            String methodName,
                            Object[] originalArguments,
                            boolean isCallToSuper,
                            boolean fromInsideClass)

      Overrides default implementation just in case invokeMethod has been overridden by ExpandoMetaClass
      Specified by:
        `invokeMethod` in interface `MetaClass`
      Overrides:
        `invokeMethod` in class `MetaClassImpl`
      Parameters:
        `sender` - The java.lang.Class instance that invoked the method
        `object` - The object which the method was invoked on
        `methodName` - The name of the method
        `originalArguments` - The arguments to the method
        `isCallToSuper` - Whether the method is a call to a super class method
        `fromInsideClass` - Whether the call was invoked from the inside or the outside of the class
      Returns:
        The return value of the method
      See Also:
        `MetaClassImpl.invokeMethod(Class, Object, String, Object[], boolean, boolean)`

    - #### invokeStaticMethod

          public Object invokeStaticMethod(Object object,
                                  String methodName,
                                  Object[] arguments)

      Overrides default implementation just in case a static invoke method has been set on ExpandoMetaClass
      Specified by:
        `invokeStaticMethod` in interface `MetaObjectProtocol`
      Overrides:
        `invokeStaticMethod` in class `MetaClassImpl`
      Parameters:
        `object` - An instance of the class returned by the getTheClass() method or the class itself
        `methodName` - The name of the method
        `arguments` - The arguments to the method
      Returns:
        The return value of the method which is null if the return type is void
      See Also:
        `MetaClassImpl.invokeStaticMethod(Object, String, Object[])`

    - #### getProperty

          public Object getProperty(Class sender,
                           Object object,
                           String name,
                           boolean useSuper,
                           boolean fromInsideClass)

      Overrides default implementation just in case getProperty method has been overridden by ExpandoMetaClass
      Specified by:
        `getProperty` in interface `MetaClass`
      Overrides:
        `getProperty` in class `MetaClassImpl`
      Parameters:
        `sender` - The java.lang.Class instance that requested the property
        `object` - The Object which the property is being retrieved from
        `name` - The name of the property
        `useSuper` - Whether the call is to a super class property
        `fromInsideClass` - ??
      Returns:
        the given property's value on the object
      See Also:
        `MetaClassImpl.getProperty(Class, Object, String, boolean, boolean)`

    - #### getProperty

          public Object getProperty(Object object,
                           String name)

      Overrides default implementation just in case getProperty method has been overridden by ExpandoMetaClass
      Specified by:
        `getProperty` in interface `MetaObjectProtocol`
      Overrides:
        `getProperty` in class `MetaClassImpl`
      Parameters:
        `object` - An instance of the class returned by the getTheClass() method
        `name` - The name of the property to retrieve the value for
      Returns:
        The properties value
      See Also:
        `MetaClassImpl.getProperty(Object, String)`

    - #### setProperty

          public void setProperty(Class sender,
                         Object object,
                         String name,
                         Object newValue,
                         boolean useSuper,
                         boolean fromInsideClass)

      Overrides default implementation just in case setProperty method has been overridden by ExpandoMetaClass
      Specified by:
        `setProperty` in interface `MetaClass`
      Overrides:
        `setProperty` in class `MetaClassImpl`
      Parameters:
        `sender` - The java.lang.Class instance that is mutating the property
        `object` - The Object which the property is being set on
        `name` - The name of the property
        `newValue` - The new value of the property to set
        `useSuper` - Whether the call is to a super class property
        `fromInsideClass` - ??
      See Also:
        `MetaClassImpl.setProperty(Class, Object, String, Object, boolean, boolean)`

    - #### getMetaProperty

          public MetaProperty getMetaProperty(String name)

      Looks up an existing MetaProperty by name
      Specified by:
        `getMetaProperty` in interface `MetaObjectProtocol`
      Overrides:
        `getMetaProperty` in class `MetaClassImpl`
      Parameters:
        `name` - The name of the MetaProperty
      Returns:
        The MetaProperty or null if it doesn't exist
      See Also:
        `MetaObjectProtocol.getMetaProperty(String)`

    - #### hasMetaProperty

          public boolean hasMetaProperty(String name)

      Returns true if the MetaClass has the given property
      Parameters:
        `name` - The name of the MetaProperty
      Returns:
        True it exists as a MetaProperty

    - #### hasMetaMethod

          public boolean hasMetaMethod(String name,
                              Class[] args)

      Checks whether a MetaMethod for the given name and arguments exists
      Parameters:
        `name` - The name of the MetaMethod
        `args` - The arguments to the meta method
      Returns:
        True if the method exists otherwise null

    - #### getPropertyForSetter

          public String getPropertyForSetter(String setterName)

      Returns a property name equivalent for the given setter name or null if it is not a getter
      Parameters:
        `setterName` - The setter name
      Returns:
        The property name equivalent

    - #### isSetter

          public boolean isSetter(String name,
                         CachedClass[] args)

    - #### createPojoCallSite

          public CallSite createPojoCallSite(CallSite site,
                                    Object receiver,
                                    Object[] args)

      Overrides:
        `createPojoCallSite` in class `MetaClassImpl`

    - #### createStaticSite

          public CallSite createStaticSite(CallSite site,
                                  Object[] args)

      Overrides:
        `createStaticSite` in class `MetaClassImpl`

    - #### createPogoCallSite

          public CallSite createPogoCallSite(CallSite site,
                                    Object[] args)

      Overrides:
        `createPogoCallSite` in class `MetaClassImpl`

    - #### createPogoCallCurrentSite

          public CallSite createPogoCallCurrentSite(CallSite site,
                                           Class sender,
                                           String name,
                                           Object[] args)

    - #### createConstructorSite

          public CallSite createConstructorSite(CallSite site,
                                       Object[] args)

      Overrides:
        `createConstructorSite` in class `MetaClassImpl`