001    /*
002     $Id: ScriptBytecodeAdapter.java 4294 2006-12-02 19:31:27Z blackdrag $
003    
004     Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
005    
006     Redistribution and use of this software and associated documentation
007     ("Software"), with or without modification, are permitted provided
008     that the following conditions are met:
009    
010     1. Redistributions of source code must retain copyright
011        statements and notices.  Redistributions must also contain a
012        copy of this document.
013    
014     2. Redistributions in binary form must reproduce the
015        above copyright notice, this list of conditions and the
016        following disclaimer in the documentation and/or other
017        materials provided with the distribution.
018    
019     3. The name "groovy" must not be used to endorse or promote
020        products derived from this Software without prior written
021        permission of The Codehaus.  For written permission,
022        please contact info@codehaus.org.
023    
024     4. Products derived from this Software may not be called "groovy"
025        nor may "groovy" appear in their names without prior written
026        permission of The Codehaus. "groovy" is a registered
027        trademark of The Codehaus.
028    
029     5. Due credit should be given to The Codehaus -
030        http://groovy.codehaus.org/
031    
032     THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS
033     ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
034     NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
035     FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
036     THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
037     INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
038     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
039     SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
040     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
041     STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
042     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
043     OF THE POSSIBILITY OF SUCH DAMAGE.
044    
045     */
046    package org.codehaus.groovy.runtime;
047    
048    import groovy.lang.*;
049    
050    import java.util.Iterator;
051    import java.util.List;
052    import java.util.ArrayList;
053    import java.util.Map;
054    import java.util.regex.Matcher;
055    import java.util.regex.Pattern;
056    
057    import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation;
058    import org.codehaus.groovy.runtime.wrappers.GroovyObjectWrapper;
059    import org.codehaus.groovy.runtime.wrappers.PojoWrapper;
060    import org.codehaus.groovy.runtime.wrappers.Wrapper;
061    
062    /**
063     * A static helper class to interface bytecode and runtime 
064     *
065     * @author Jochen Theodorou
066     * @version $Revision: 4294 $
067     */
068    public class ScriptBytecodeAdapter {
069        public static final Object[] EMPTY_ARGS = {};
070        private static final Integer ZERO = new Integer(0);
071        private static final Integer MINUS_ONE = new Integer(-1);
072        private static final Integer ONE = new Integer(1);
073    
074        //  --------------------------------------------------------
075        //                   exception handling
076        //  --------------------------------------------------------
077        private static Object unwrap(GroovyRuntimeException gre) throws Throwable{
078            Throwable th = gre;
079            if (th.getCause()!=null && th.getCause()!=gre) th=th.getCause();
080            if (th!=gre && (th instanceof GroovyRuntimeException)) unwrap((GroovyRuntimeException) th);
081            throw th;
082        }
083        
084        //  --------------------------------------------------------
085        //                       methods for this
086        //  --------------------------------------------------------
087        public static Object invokeMethodOnCurrentN(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable{
088            Object result=null;
089            try {
090                try {
091                    // if it's a pure interceptable object (even intercepting toString(), clone(), ...)
092                    if (receiver instanceof GroovyInterceptable) {
093                        result = receiver.invokeMethod(messageName, messageArguments);
094                    }
095                    //else if there's a statically typed method or a GDK method
096                    else {
097                        result = receiver.getMetaClass().invokeMethod(senderClass, receiver, messageName, messageArguments, false, true);
098                    }
099                } catch (MissingMethodException e) {
100                    if (receiver.getClass() == e.getType() && e.getMethod().equals(messageName)) {
101                        // in case there's nothing else, invoke the object's own invokeMethod()
102                        result = receiver.invokeMethod(messageName, messageArguments);
103                    } else {
104                        throw e;
105                    }
106                }
107            } catch (GroovyRuntimeException t) {
108                unwrap(t);
109            }
110            return result;
111        }
112        
113        public static Object invokeMethodOnCurrentNSafe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable{
114            return invokeMethodOnCurrentN(senderClass,receiver,messageName,messageArguments);
115        }
116        
117        public static Object invokeMethodOnCurrentNSpreadSafe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable{
118            if (! (receiver instanceof List)) return invokeMethodOnCurrentN(senderClass,receiver,messageName, messageArguments);
119            
120            List list = (List) receiver;
121            List answer = new ArrayList();
122            for (Iterator it = list.iterator(); it.hasNext();) {
123                answer.add(invokeMethodNSafe(senderClass, it.next(), messageName, messageArguments));
124            }
125            return answer;
126        }
127        
128        public static Object invokeMethodOnCurrent0(Class senderClass, GroovyObject receiver, String messageName)  throws Throwable{
129            return invokeMethodOnCurrentN(senderClass,receiver,messageName,EMPTY_ARGS);
130        }
131        
132        public static Object invokeMethodOnCurrent0Safe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable{
133            return invokeMethodOnCurrentNSafe(senderClass,receiver,messageName,EMPTY_ARGS);
134        }
135        
136        public static Object invokeMethodOnCurrent0SpreadSafe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable{
137            return invokeMethodOnCurrentNSpreadSafe(senderClass,receiver,messageName,EMPTY_ARGS);
138        }
139        
140        //  --------------------------------------------------------
141        //                       methods for super
142        //  --------------------------------------------------------
143        public static Object invokeMethodOnSuperN(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable{
144            MetaClass metaClass = receiver.getMetaClass();
145            // ignore interception and missing method fallback
146            Object result=null;
147            try {
148                result = metaClass.invokeMethod(senderClass, receiver, messageName, messageArguments, true, true);
149            } catch (GroovyRuntimeException t) {
150                unwrap(t);
151            }
152            return result;        
153        }
154        
155        public static Object invokeMethodOnSuperNSafe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable{
156            return invokeMethodOnSuperN(senderClass,receiver,messageName,messageArguments);
157        }
158        
159        public static Object invokeMethodOnSuperNSpreadSafe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable{
160            if (! (receiver instanceof List)) return invokeMethodOnSuperN(senderClass,receiver,messageName, messageArguments);
161            
162            List list = (List) receiver;
163            List answer = new ArrayList();
164            for (Iterator it = list.iterator(); it.hasNext();) {
165                answer.add(invokeMethodNSafe(senderClass,it.next(), messageName, messageArguments));
166            }
167            return answer;
168        }
169        
170        public static Object invokeMethodOnSuper0(Class senderClass, GroovyObject receiver, String messageName)  throws Throwable{
171            return invokeMethodOnSuperN(senderClass,receiver,messageName,EMPTY_ARGS);
172        }
173        
174        public static Object invokeMethodOnSuper0Safe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable{
175            return invokeMethodOnSuperNSafe(senderClass,receiver,messageName,EMPTY_ARGS);
176        }
177        
178        public static Object invokeMethodOnSuper0SpreadSafe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable{
179            return invokeMethodOnSuperNSpreadSafe(senderClass,receiver,messageName,EMPTY_ARGS);
180        }
181    
182        //  --------------------------------------------------------
183        //              normal method invocation
184        //  --------------------------------------------------------       
185        public static Object invokeMethodN(Class senderClass, Object receiver, String messageName, Object[] messageArguments) throws Throwable{
186            try {
187                return InvokerHelper.invokeMethod(receiver, messageName, messageArguments);
188            } catch (GroovyRuntimeException gre) {
189                return unwrap(gre);
190            }
191        }
192        
193        public static Object invokeMethodNSafe(Class senderClass, Object receiver, String messageName, Object[] messageArguments) throws Throwable{
194            if (receiver==null) return null;
195            return invokeMethodN(senderClass,receiver,messageName,messageArguments);
196        }
197        
198        public static Object invokeMethodNSpreadSafe(Class senderClass, Object receiver, String messageName, Object[] messageArguments) throws Throwable{
199            if (receiver==null) return null;
200            if (! (receiver instanceof List)) return invokeMethodN(senderClass,receiver,messageName, messageArguments);
201            
202            List list = (List) receiver;
203            List answer = new ArrayList();
204            for (Iterator it = list.iterator(); it.hasNext();) {
205                answer.add(invokeMethodNSafe(senderClass, it.next(), messageName, messageArguments));
206            }
207            return answer;
208        }
209        
210        public static Object invokeMethod0(Class senderClass, Object receiver, String messageName)  throws Throwable{
211            return invokeMethodN(senderClass,receiver,messageName,EMPTY_ARGS);
212        }
213        
214        public static Object invokeMethod0Safe(Class senderClass, Object receiver, String messageName) throws Throwable{
215            if (receiver==null) return null;
216            return invokeMethodNSafe(senderClass,receiver,messageName,EMPTY_ARGS);
217        }
218        
219        public static Object invokeMethod0SpreadSafe(Class senderClass, Object receiver, String messageName) throws Throwable{
220            return invokeMethodNSpreadSafe(senderClass,receiver,messageName,EMPTY_ARGS);
221        }
222        
223        //  --------------------------------------------------------
224        //                static normal method invocation
225        //  --------------------------------------------------------       
226        public static Object invokeStaticMethodN(Class senderClass, Class receiver, String messageName, Object[] messageArguments) throws Throwable{
227            try {
228                return InvokerHelper.invokeStaticMethod(receiver, messageName, messageArguments);
229            } catch (GroovyRuntimeException gre) {
230                return unwrap(gre);
231            }
232        }
233        
234        public static Object invokeStaticMethod0(Class senderClass, Class receiver, String messageName)  throws Throwable{
235            return invokeStaticMethodN(senderClass,receiver,messageName,EMPTY_ARGS);
236        }
237        
238        //  --------------------------------------------------------
239        //              normal constructor invocation (via new)
240        //  --------------------------------------------------------       
241        public static Object invokeNewN(Class senderClass, Class receiver, Object arguments) throws Throwable{
242            try {
243                return InvokerHelper.invokeConstructorOf(receiver, arguments);
244            } catch (GroovyRuntimeException gre) {
245                return unwrap(gre);
246            }  
247        }
248        
249        public static Object invokeNew0(Class senderClass, Class receiver) throws Throwable {
250            return invokeNewN(senderClass, receiver, EMPTY_ARGS);
251        }
252    
253        //  --------------------------------------------------------
254        //       special constructor invocation (via this/super)
255        //  --------------------------------------------------------       
256    
257        public static int selectConstructorAndTransformArguments(Object[] arguments, int numberOfCosntructors, Class which) {
258            MetaClassImpl metaClass = (MetaClassImpl) InvokerHelper.getInstance().getMetaRegistry().getMetaClass(which);
259            return metaClass.selectConstructorAndTransformArguments(numberOfCosntructors, arguments);
260        }
261    
262        //  --------------------------------------------------------
263        //              field handling super: get
264        //  --------------------------------------------------------       
265    
266        public static Object getFieldOnSuper(Class senderClass, Object receiver, String messageName) throws Throwable{
267            try {
268                if (receiver instanceof Class) {
269                    return InvokerHelper.getAttribute(receiver,messageName); 
270                } else {            
271                    MetaClass mc = ((GroovyObject) receiver).getMetaClass();
272                    return mc.getAttribute(senderClass, receiver, messageName, true);
273                }
274            } catch (GroovyRuntimeException gre) {
275                return unwrap(gre);
276            }
277        }
278        
279        public static Object getFieldOnSuperSafe(Class senderClass, Object receiver, String messageName) throws Throwable{
280            return getFieldOnSuper(senderClass,receiver,messageName);
281        }
282        
283        public static Object getFieldOnSuperSpreadSafe(Class senderClass, Object receiver, String messageName) throws Throwable{
284            if (! (receiver instanceof List)) return getFieldOnSuper(senderClass,receiver,messageName);
285            
286            List list = (List) receiver;
287            List answer = new ArrayList();
288            for (Iterator it = list.iterator(); it.hasNext();) {
289                answer.add(getFieldOnSuper(senderClass, it.next(), messageName));
290            }
291            return answer;
292        }
293    
294        //  --------------------------------------------------------
295        //              field handling super: set
296        //  --------------------------------------------------------       
297    
298        public static void setFieldOnSuper(Object messageArgument,Class senderClass, Object receiver, String messageName) throws Throwable{
299            try {
300                if (receiver instanceof Class) {
301                    InvokerHelper.setAttribute(receiver,messageName,messageArgument); 
302                } else {          
303                    MetaClass mc = ((GroovyObject) receiver).getMetaClass();
304                    mc.setAttribute(senderClass, receiver, messageName, messageArgument, true, true);
305                }
306            } catch (GroovyRuntimeException gre) {
307                unwrap(gre);
308            }
309        }
310        
311        public static void setFieldOnSuperSafe(Object messageArgument,Class senderClass, Object receiver, String messageName) throws Throwable{
312            setFieldOnSuper(messageArgument,senderClass,receiver,messageName);
313        }
314        
315        public static void setFieldOnSuperSpreadSafe(Object messageArgument,Class senderClass, Object receiver, String messageName) throws Throwable{
316            if (! (receiver instanceof List)) {
317                setFieldOnSuper(messageArgument,senderClass,receiver,messageName);
318                return;
319            }
320            
321            List list = (List) receiver;
322            List answer = new ArrayList();
323            for (Iterator it = list.iterator(); it.hasNext();) {
324                setFieldOnSuper(messageArgument,senderClass, it.next(), messageName);
325            }
326        }
327    
328        
329        //  --------------------------------------------------------
330        //              normal field handling : get
331        //  --------------------------------------------------------       
332    
333        public static Object getField(Class senderClass, Object receiver, String messageName) throws Throwable{
334            try {
335                return InvokerHelper.getAttribute(receiver, messageName);
336            } catch (GroovyRuntimeException gre) {
337                return unwrap(gre);
338            }
339        }
340        
341        public static Object getFieldSafe(Class senderClass, Object receiver, String messageName) throws Throwable{
342            if (receiver==null) return null;
343            return getField(senderClass,receiver,messageName);
344        }
345        
346        public static Object getFieldSpreadSafe(Class senderClass, Object receiver, String messageName) throws Throwable{
347            if (receiver==null) return null;
348            if (! (receiver instanceof List)) return getField(senderClass,receiver,messageName);
349            
350            List list = (List) receiver;
351            List answer = new ArrayList();
352            for (Iterator it = list.iterator(); it.hasNext();) {
353                answer.add(getFieldSafe(senderClass, it.next(), messageName));
354            }
355            return answer;
356        }
357    
358        //  --------------------------------------------------------
359        //              normal field handling : set
360        //  --------------------------------------------------------       
361    
362        public static void setField(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable{
363            try {
364                InvokerHelper.setAttribute(receiver, messageName,messageArgument);
365            } catch (GroovyRuntimeException gre) {
366                unwrap(gre);
367            }
368        }
369        
370        public static void setFieldSafe(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable{
371            if (receiver==null) return;
372            setField(messageArgument,senderClass,receiver,messageName);
373        }
374        
375        public static void setFieldSpreadSafe(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable{
376            if (receiver==null) return;
377            if (! (receiver instanceof List)) {
378                setField(messageArgument,senderClass,receiver,messageName);
379                return;
380            }
381            
382            List list = (List) receiver;
383            List answer = new ArrayList();
384            for (Iterator it = list.iterator(); it.hasNext();) {
385                setFieldSafe(messageArgument,senderClass, it.next(), messageName);
386            }
387        }
388        
389        //  --------------------------------------------------------
390        //              normal GroovyObject field handling : get
391        //  --------------------------------------------------------       
392    
393        public static Object getGroovyObjectField(Class senderClass, GroovyObject receiver, String messageName) throws Throwable{
394            return receiver.getMetaClass().getAttribute(receiver,messageName);
395        }
396        
397        public static Object getGroovyObjectFieldSafe(Class senderClass, GroovyObject receiver, String messageName) throws Throwable{
398            if (receiver==null) return null;
399            return receiver.getMetaClass().getAttribute(receiver,messageName);
400        }
401        
402        public static Object getGroovyObjectFieldSpreadSafe(Class senderClass, GroovyObject receiver, String messageName) throws Throwable{
403            if (receiver==null) return null;
404            if (! (receiver instanceof List)) return getGroovyObjectField(senderClass,receiver,messageName);
405            
406            List list = (List) receiver;
407            List answer = new ArrayList();
408            for (Iterator it = list.iterator(); it.hasNext();) {
409                answer.add(getFieldSafe(senderClass, it.next(), messageName));
410            }
411            return answer;
412        }
413    
414        //  --------------------------------------------------------
415        //              normal field handling : set
416        //  --------------------------------------------------------       
417    
418        public static void setGroovyObjectField(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable{
419            receiver.getMetaClass().setAttribute(receiver,messageName,messageArgument);
420        }
421        
422        public static void setGroovyObjectFieldSafe(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable{
423            if (receiver==null) return;
424            receiver.getMetaClass().setAttribute(receiver,messageName,messageArgument);
425        }
426        
427        public static void setGroovyObjectFieldSpreadSafe(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable{
428            if (receiver==null) return;
429            if (! (receiver instanceof List)) {
430                setGroovyObjectField(messageArgument,senderClass,receiver,messageName);
431                return;
432            }
433            
434            List list = (List) receiver;
435            List answer = new ArrayList();
436            for (Iterator it = list.iterator(); it.hasNext();) {
437                setFieldSafe(messageArgument,senderClass, it.next(), messageName);
438            }
439        }
440    
441        //  --------------------------------------------------------
442        //              Property handling super: get
443        //  --------------------------------------------------------       
444    
445        public static Object getPropertyOnSuper(Class senderClass, GroovyObject receiver, String messageName) throws Throwable{
446            return invokeMethodOnSuperN(senderClass, receiver, "getProperty", new Object[]{messageName});
447        }
448        
449        public static Object getPropertyOnSuperSafe(Class senderClass, GroovyObject receiver, String messageName) throws Throwable{
450            return getPropertyOnSuper(senderClass,receiver,messageName);
451        }
452        
453        public static Object getPropertyOnSuperSpreadSafe(Class senderClass, GroovyObject receiver, String messageName) throws Throwable{
454            if (! (receiver instanceof List)) return getPropertyOnSuper(senderClass,receiver,messageName);
455            
456            List list = (List) receiver;
457            List answer = new ArrayList();
458            for (Iterator it = list.iterator(); it.hasNext();) {
459                answer.add(getPropertySafe(senderClass, it.next(), messageName));
460            }
461            return answer;
462        }
463    
464        //  --------------------------------------------------------
465        //              Property handling super: set
466        //  --------------------------------------------------------       
467    
468        public static void setPropertyOnSuper(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable{
469            try {
470                InvokerHelper.setAttribute(receiver, messageName,messageArgument);
471            } catch (GroovyRuntimeException gre) {
472                unwrap(gre);
473            }
474        }
475        
476        public static void setPropertyOnSuperSafe(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable{
477            setPropertyOnSuper(messageArgument, senderClass,receiver,messageName);
478        }
479        
480        public static void setPropertyOnSuperSpreadSafe(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable{
481            if (! (receiver instanceof List)) {
482                setPropertyOnSuper(messageArgument, senderClass,receiver,messageName);
483                return;
484            }
485            
486            List list = (List) receiver;
487            List answer = new ArrayList();
488            for (Iterator it = list.iterator(); it.hasNext();) {
489                setPropertySafe(messageArgument, senderClass, it.next(), messageName);
490            }
491        }
492    
493        
494        //  --------------------------------------------------------
495        //              normal Property handling : get
496        //  --------------------------------------------------------       
497    
498        public static Object getProperty(Class senderClass, Object receiver, String messageName) throws Throwable{
499            try {
500                return InvokerHelper.getProperty(receiver, messageName);
501            } catch (GroovyRuntimeException gre) {
502                return unwrap(gre);
503            }
504        }
505        
506        public static Object getPropertySafe(Class senderClass, Object receiver, String messageName) throws Throwable{
507            if (receiver==null) return null;
508            return getProperty(senderClass,receiver,messageName);
509        }
510        
511        public static Object getPropertySpreadSafe(Class senderClass, Object receiver, String messageName) throws Throwable{
512            if (receiver==null) return null;
513            if (! (receiver instanceof List)) return getProperty(senderClass,receiver,messageName);
514            
515            List list = (List) receiver;
516            List answer = new ArrayList();
517            for (Iterator it = list.iterator(); it.hasNext();) {
518                answer.add(getPropertySafe(senderClass, it.next(), messageName));
519            }
520            return answer;
521        }
522        
523        //  --------------------------------------------------------
524        //              normal Property handling : set
525        //  --------------------------------------------------------       
526    
527        public static void setProperty(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable{
528            try {
529                InvokerHelper.setProperty(receiver, messageName,messageArgument);
530            } catch (GroovyRuntimeException gre) {
531                unwrap(gre);
532            }
533        }
534        
535        public static void setPropertySafe(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable{
536            if (receiver==null) return;
537            setProperty(messageArgument,senderClass,receiver,messageName);
538        }
539        
540        public static void setPropertySpreadSafe(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable{
541            if (receiver==null) return;
542            if (! (receiver instanceof List)) {
543                setProperty(messageArgument, senderClass, receiver, messageName);
544                return;
545            }
546            
547            List list = (List) receiver;
548            List answer = new ArrayList();
549            for (Iterator it = list.iterator(); it.hasNext();) {
550                setPropertySafe(messageArgument, senderClass, it.next(), messageName);
551            }
552        }
553        
554        
555        //  --------------------------------------------------------
556        //              normal GroovyObject Property handling : get
557        //  --------------------------------------------------------       
558    
559        public static Object getGroovyObjectProperty(Class senderClass, GroovyObject receiver, String messageName) throws Throwable{
560            return receiver.getProperty(messageName);
561        }
562        
563        public static Object getGroovyObjectPropertySafe(Class senderClass, GroovyObject receiver, String messageName) throws Throwable{
564            if (receiver==null) return null;
565            return receiver.getProperty(messageName);
566        }
567        
568        public static Object getGroovyObjectPropertySpreadSafe(Class senderClass, GroovyObject receiver, String messageName) throws Throwable{
569            if (receiver==null) return null;
570            if (! (receiver instanceof List)) return getGroovyObjectProperty(senderClass,receiver,messageName);
571            
572            List list = (List) receiver;
573            List answer = new ArrayList();
574            for (Iterator it = list.iterator(); it.hasNext();) {
575                answer.add(getPropertySafe(senderClass, it.next(), messageName));
576            }
577            return answer;
578        }
579    
580        //  --------------------------------------------------------
581        //              normal GroovyObject Property handling : set
582        //  --------------------------------------------------------       
583    
584        public static void setGroovyObjectProperty(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable{
585            receiver.setProperty(messageName,messageArgument);
586        }
587        
588        public static void setGroovyObjectPropertySafe(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable{
589            if (receiver==null) return;
590            receiver.setProperty(messageName,messageArgument);
591        }
592        
593        public static void setGroovyObjectPropertySpreadSafe(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable{
594            if (receiver==null) return;
595            if (! (receiver instanceof List)) {
596                setProperty(messageArgument, senderClass, receiver, messageName);
597                return;
598            }
599            
600            List list = (List) receiver;
601            List answer = new ArrayList();
602            for (Iterator it = list.iterator(); it.hasNext();) {
603                setPropertySafe(messageArgument, senderClass, it.next(), messageName);
604            }
605        }
606        
607        //  **********************************************************************************
608        //  **********************************************************************************
609        //  **************          methods not covered by the new MOP          **************
610        //  **********************************************************************************
611        //  **********************************************************************************
612        
613        //  --------------------------------------------------------
614        //                     Closures
615        //  --------------------------------------------------------           
616        
617        /**
618         * Returns the method pointer for the given object name
619         */
620        public static Closure getMethodPointer(Object object, String methodName) {
621            return InvokerHelper.getMethodPointer(object, methodName);
622        }
623        
624        // TODO: set sender class
625        public static Object invokeClosure(Object closure, Object[] arguments) throws Throwable {
626            return invokeMethodN(closure.getClass(), closure, "doCall", arguments);
627        } 
628            
629    
630        //  --------------------------------------------------------
631        //                     type conversion
632        //  --------------------------------------------------------           
633              
634        /**
635         * Provides a hook for type coercion of the given object to the required type
636         *
637         * @param type   of object to convert the given object to
638         * @param object the object to be converted
639         * @return the original object or a new converted value
640         * @throws Throwable 
641         */
642        public static Object asType(Object object, Class type) throws Throwable {
643            return invokeMethodN(object.getClass(),object,"asType",new Object[]{type});
644        }
645        
646        /**
647         * Provides a hook for type casting of the given object to the required type
648         * 
649         * @param type   of object to convert the given object to
650         * @param object the object to be converted
651         * @return the original object or a new converted value
652         * @throws Throwable 
653         */
654        public static Object castToType(Object object, Class type) throws Throwable{
655            try {
656                return DefaultTypeTransformation.castToType(object,type);
657            } catch (GroovyRuntimeException gre) {
658                return (Matcher) unwrap(gre);
659            }
660        }    
661    
662        public static Tuple createTuple(Object[] array) {
663            return new Tuple(array);
664        }
665    
666        public static List createList(Object[] values) {
667            return InvokerHelper.createList(values);
668        }
669        
670        public static Wrapper createPojoWrapper(Object val, Class clazz) {
671            return new PojoWrapper(val,clazz);
672        }
673    
674        public static Wrapper createGroovyObjectWrapper(GroovyObject val, Class clazz) {
675            return new GroovyObjectWrapper(val,clazz);
676        }
677        
678        public static Map createMap(Object[] values) {
679            return InvokerHelper.createMap(values);
680        }
681        
682    
683        //TODO: refactor
684        public static List createRange(Object from, Object to, boolean inclusive) throws Throwable {
685            if (!inclusive) {
686                if (compareEqual(from,to)){
687                    return new EmptyRange((Comparable)from);
688                }
689                if (compareGreaterThan(from, to)) {
690                    to = invokeMethod0(ScriptBytecodeAdapter.class, to, "next");
691                }
692                else {
693                    to = invokeMethod0(ScriptBytecodeAdapter.class, to, "previous");
694                }
695            }
696            if (from instanceof Integer && to instanceof Integer) {
697                return new IntRange(DefaultTypeTransformation.intUnbox(from), DefaultTypeTransformation.intUnbox(to));
698            }
699            else {
700                return new ObjectRange((Comparable) from, (Comparable) to);
701            }
702        }
703        
704        //assert
705        public static void assertFailed(Object expression, Object message) {
706            InvokerHelper.assertFailed(expression,message);
707        }
708    
709        //isCase
710        //TODO: set sender class
711        public static boolean isCase(Object switchValue, Object caseExpression) throws Throwable{
712            if (caseExpression == null) {
713                return switchValue == null;
714            }
715            return DefaultTypeTransformation.castToBoolean(invokeMethodN(caseExpression.getClass(), caseExpression, "isCase", new Object[]{switchValue}));
716        }
717        
718        //compare
719        public static boolean compareIdentical(Object left, Object right) {
720            return left == right;
721        }
722        
723        public static boolean compareEqual(Object left, Object right) {
724            return DefaultTypeTransformation.compareEqual(left, right);
725        }
726        
727        public static boolean compareNotEqual(Object left, Object right) {
728            return !compareEqual(left, right);
729        }
730        
731        public static Integer compareTo(Object left, Object right) {
732            int answer = DefaultTypeTransformation.compareTo(left, right);
733            if (answer == 0) {
734                return ZERO;
735            }
736            else {
737                return answer > 0 ? ONE : MINUS_ONE;
738            }
739        }    
740    
741        public static boolean compareLessThan(Object left, Object right) {
742            return compareTo(left, right).intValue() < 0;
743        }
744        
745        public static boolean compareLessThanEqual(Object left, Object right){
746            return compareTo(left, right).intValue() <= 0;
747        }
748        
749        public static boolean compareGreaterThan(Object left, Object right){
750            return compareTo(left, right).intValue() > 0;
751        }
752    
753        public static boolean compareGreaterThanEqual(Object left, Object right){
754            return compareTo(left, right).intValue() >= 0;
755        }
756    
757        //regexpr
758        public static Pattern regexPattern(Object regex) {
759            return DefaultGroovyMethods.negate(regex.toString());
760        }
761        
762        public static Matcher findRegex(Object left, Object right) throws Throwable{
763            try {
764                return InvokerHelper.findRegex(left, right);
765            } catch (GroovyRuntimeException gre) {
766                return (Matcher) unwrap(gre);
767            }
768        }
769        
770        public static boolean matchRegex(Object left, Object right) {
771            return InvokerHelper.matchRegex(left, right);
772        }
773        
774        
775        //spread expressions
776        public static Object[] despreadList(Object[] args, Object[] spreads, int[] positions) {
777            ArrayList ret = new ArrayList();
778            int argsPos = 0;
779            int spreadPos = 0;
780            for (int pos = 0; pos<positions.length; pos++) {
781                for (;argsPos<positions[pos];argsPos++) {
782                    ret.add(args[argsPos]);
783                }
784                Object value = spreads[spreadPos];
785                if (value==null) {
786                    ret.add(null);
787                } else if (value instanceof List) {
788                    ret.addAll((List) value);
789                } else if (value.getClass().isArray()) {
790                    ret.addAll(DefaultTypeTransformation.primitiveArrayToList(value));
791                } else {
792                    throw new IllegalArgumentException("connot spread the type "+ value.getClass().getName()+" with value "+value);
793                }
794                spreadPos++;
795            }
796            for (;argsPos<args.length;argsPos++) {
797                ret.add(args[argsPos]);
798            }
799            return ret.toArray();
800        }
801        
802        public static Object spreadMap(Object value) {
803            return InvokerHelper.spreadMap(value);
804        }
805        
806        //negation
807        public static Object negate(Object value) throws Throwable {
808            try {
809                return InvokerHelper.negate(value);
810            } catch (GroovyRuntimeException gre) {
811                return unwrap(gre);
812            }
813        }
814        
815        public static Object bitNegate(Object value) {
816            return InvokerHelper.bitNegate(value);
817        }
818    
819        public static MetaClass initMetaClass(Object object) {
820            return InvokerHelper.getMetaClass(object);
821        }
822        
823        private static MetaClass getMetaClassObjectNotNull(Object object) {
824            if (!(object instanceof GroovyObject)) {
825                return initMetaClass(object);
826            } else {
827                return ((GroovyObject) object).getMetaClass();
828            }        
829        }
830        
831        
832    
833    }