001    /*
002     $Id: ScriptBytecodeAdapter.java,v 1.11 2005/10/03 18:07:36 tug Exp $
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    /**
058     * A static helper class to make bytecode generation easier and act as a facade over the Invoker. 
059     *
060     * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
061     * @version $Revision: 1.11 $
062     */
063    public class ScriptBytecodeAdapter {
064        public static final Object[] EMPTY_ARGS = {
065        };
066    /*
067        private static final Object[] EMPTY_MAIN_ARGS = new Object[]{new String[0]};
068    
069        private static final Invoker singleton = new Invoker();
070    
071        private static final Integer ZERO = new Integer(0);
072        private static final Integer MINUS_ONE = new Integer(-1);
073        private static final Integer ONE = new Integer(1);*/
074    
075        
076        private static Object unwrap(GroovyRuntimeException gre) throws Throwable{
077            Throwable th = gre;
078            if (th.getCause()!=null && th.getCause()!=gre) th=th.getCause();
079            if (th!=gre && (th instanceof GroovyRuntimeException)) unwrap((GroovyRuntimeException) th);
080            throw th;
081        }
082    
083        public static Object invokeMethod(Object object, String methodName, Object arguments)  throws Throwable{
084            try {
085                return InvokerHelper.invokeMethod(object, methodName, arguments);
086            } catch (GroovyRuntimeException gre) {
087                return unwrap(gre);
088            }
089        }
090        
091        public static Object invokeMethodSafe(Object object, String methodName, Object arguments) throws Throwable{
092            if (object != null) return invokeMethod(object, methodName, arguments);
093            return null;
094        }    
095    
096        public static Object invokeMethodSpreadSafe(Object object, String methodName, Object arguments) throws Throwable{
097            if (object != null) {
098                if (object instanceof List) {
099                    List list = (List) object;
100                    List answer = new ArrayList();
101                    Iterator it = list.iterator();
102                    for (; it.hasNext();) {
103                        answer.add(invokeMethodSafe(it.next(), methodName, arguments));
104                    }
105                    return answer;
106                }
107                else
108                    return invokeMethodSafe(object, methodName, arguments);
109            }
110            return null;
111        }    
112    
113        public static Object invokeStaticMethod(String type, String methodName, Object arguments) throws Throwable{
114            try {
115                return InvokerHelper.invokeStaticMethod(type, methodName, arguments);
116            } catch (GroovyRuntimeException gre) {
117                return unwrap(gre);
118            }
119        }
120    
121        public static Object invokeConstructorAt(Class at, Class type, Object arguments) throws Throwable{
122            try {
123                return InvokerHelper.invokeConstructorAt(at, type, arguments);
124            } catch (GroovyRuntimeException gre) {
125                return unwrap(gre);
126            }
127        }
128    
129        /// public static Object invokeConstructorAt(Class at, String type, Object arguments) throws Throwable{
130        ///     try {
131        ///         return InvokerHelper.invokeConstructorAt(at, type, arguments);
132        ///     } catch (GroovyRuntimeException gre) {
133        ///         return unwrap(gre);
134        ///     }
135        /// }
136    
137        public static Object invokeNoArgumentsConstructorAt(Class at, Class type) throws Throwable {
138            return invokeConstructorAt(at, type, EMPTY_ARGS);
139        }
140        
141        
142        public static Object invokeConstructorOf(Class type, Object arguments) throws Throwable{
143            try {
144                return InvokerHelper.invokeConstructorOf(type, arguments);
145            } catch (GroovyRuntimeException gre) {
146                return unwrap(gre);
147            }  
148        }
149        
150        /// public static Object invokeConstructorOf(String type, Object arguments) throws Throwable{
151        ///     try {
152        ///         return InvokerHelper.invokeConstructorOf(type, arguments);
153        ///     } catch (GroovyRuntimeException gre) {
154        ///         return unwrap(gre);
155        ///     }  
156        /// }
157        
158        public static Object invokeNoArgumentsConstructorOf(Class type) throws Throwable {
159            return invokeConstructorOf(type, EMPTY_ARGS);
160        }
161        
162        public static Object invokeClosure(Object closure, Object arguments) throws Throwable {
163            return invokeMethod(closure, "doCall", arguments);
164        }    
165        
166        public static Object invokeSuperMethod(Object object, String methodName, Object arguments) throws Throwable{
167            try {
168                return InvokerHelper.invokeSuperMethod(object, methodName, arguments);
169            } catch (GroovyRuntimeException gre) {
170                return unwrap(gre);
171            } 
172        }
173        
174        public static Object invokeNoArgumentsMethod(Object object, String methodName) throws Throwable {
175            return invokeMethod(object, methodName, EMPTY_ARGS);
176        }
177        
178        public static Object invokeNoArgumentsMethodSafe(Object object, String methodName) throws Throwable {
179            if (object != null) return invokeNoArgumentsMethod(object, methodName);
180            return null;
181        }
182        
183        public static Object invokeNoArgumentsMethodSpreadSafe(Object object, String methodName) throws Throwable {
184            if (object != null) {
185                if (object instanceof List) {
186                    List list = (List) object;
187                    List answer = new ArrayList();
188                    Iterator it = list.iterator();
189                    for (; it.hasNext();) {
190                        answer.add(invokeNoArgumentsMethod(it.next(), methodName));
191                    }
192                    return answer;
193                }
194                else
195                    return invokeNoArgumentsMethod(object, methodName);
196            }
197            return null;
198        }
199        
200        public static Object invokeStaticNoArgumentsMethod(String type, String methodName) throws Throwable {
201            return invokeStaticMethod(type, methodName, EMPTY_ARGS);
202        }
203        
204        public static int asInt(Object value) throws Throwable {
205            try {
206                return InvokerHelper.asInt(value);
207            } catch (GroovyRuntimeException gre) {
208               unwrap(gre);
209               // return never reached
210               return -1;
211            }
212        }
213        
214        /**
215         * Provides a hook for type coercion of the given object to the required type
216         *
217         * @param type   of object to convert the given object to
218         * @param object the object to be converted
219         * @return the original object or a new converted value
220         * @throws Throwable 
221         */
222        public static Object asType(Object object, Class type) throws Throwable {
223            try {
224                return InvokerHelper.asType(object, type);
225            } catch (GroovyRuntimeException gre) {
226                return unwrap(gre);
227            }
228        }
229    
230    
231    
232        // Attributes
233        //-------------------------------------------------------------------------
234        public static Object getAttribute(Object object, String attribute) throws Throwable {
235            try {
236                return InvokerHelper.getAttribute(object, attribute);
237            } catch (GroovyRuntimeException gre) {
238                return unwrap(gre);
239            }
240        }
241    
242        public static Object getAttributeSafe(Object object, String attribute) throws Throwable {
243            if (object != null) return getAttribute(object, attribute);
244            return null;
245        }
246    
247        public static Object getAttributeSpreadSafe(Object object, String attribute) throws Throwable {
248            if (object != null) {
249                if (object instanceof List) {
250                    List list = (List) object;
251                    List answer = new ArrayList();
252                    Iterator it = list.iterator();
253                    for (; it.hasNext(); ) {
254                        answer.add(getAttributeSafe(it.next(), attribute));
255                    }
256                    return answer;
257                }
258                else
259                    return getAttributeSafe(object, attribute);
260            }
261            return null;
262        }
263    
264        public static void setAttribute(Object object, String attribute, Object newValue) throws Throwable {
265            try {
266                InvokerHelper.setAttribute(object, attribute, newValue);
267            } catch (GroovyRuntimeException gre) {
268                unwrap(gre);
269            }
270        }
271        /**
272         * This is so we don't have to reorder the stack when we call this method.
273         * At some point a better name might be in order.
274         * @throws Throwable
275         */
276        public static void setAttribute2(Object newValue, Object object, String property) throws Throwable {
277            setAttribute(object, property, newValue);
278        }
279    
280        /**
281         * This is so we don't have to reorder the stack when we call this method.
282         * At some point a better name might be in order.
283         * @throws Throwable
284         */
285        public static void setAttributeSafe2(Object newValue, Object object, String property) throws Throwable {
286            setAttribute2(newValue, object, property);
287        }
288    
289    
290    
291        // Properties
292        //-------------------------------------------------------------------------
293        public static Object getProperty(Object object, String property) throws Throwable {
294            try {
295                return InvokerHelper.getProperty(object, property);
296            } catch (GroovyRuntimeException gre) {
297                return unwrap(gre);
298            }
299        }
300    
301        public static Object getPropertySafe(Object object, String property) throws Throwable {
302            if (object != null) return getProperty(object, property);
303            return null;
304        }
305    
306        public static Object getPropertySpreadSafe(Object object, String property) throws Throwable {
307            if (object != null) {
308                if (object instanceof List) {
309                    List list = (List) object;
310                    List answer = new ArrayList();
311                    Iterator it = list.iterator();
312                    for (; it.hasNext(); ) {
313                        answer.add(getPropertySafe(it.next(), property));
314                    }
315                    return answer;
316                }
317                else
318                    return getPropertySafe(object, property);
319            }
320            return null;
321        }
322    
323        public static void setProperty(Object object, String property, Object newValue) throws Throwable {
324            try {
325                InvokerHelper.setProperty(object, property, newValue);
326            } catch (GroovyRuntimeException gre) {
327                unwrap(gre);
328            }
329        }
330        
331        /**
332         * This is so we don't have to reorder the stack when we call this method.
333         * At some point a better name might be in order.
334         * @throws Throwable 
335         */
336        public static void setProperty2(Object newValue, Object object, String property) throws Throwable {
337            setProperty(object, property, newValue);
338        }
339    
340        /**
341         * This is so we don't have to reorder the stack when we call this method.
342         * At some point a better name might be in order.
343         * @throws Throwable 
344         */
345        public static void setPropertySafe2(Object newValue, Object object, String property) throws Throwable {
346            setProperty2(newValue, object, property);
347        }
348    
349    
350        /**
351         * This is so we don't have to reorder the stack when we call this method.
352         * At some point a better name might be in order.
353         * @throws Throwable 
354         */
355        public static void setGroovyObjectProperty(Object newValue, GroovyObject object, String property) throws Throwable {
356            try {
357                object.setProperty(property, newValue);
358            } catch (GroovyRuntimeException gre) {
359                unwrap(gre);
360            }
361        }
362    
363        public static Object getGroovyObjectProperty(GroovyObject object, String property) throws Throwable {
364            try {
365                return object.getProperty(property);
366            } catch (GroovyRuntimeException gre) {
367                return unwrap(gre);
368            }
369        }
370    
371    
372        /**
373         * Returns the method pointer for the given object name
374         */
375        public static Closure getMethodPointer(Object object, String methodName) {
376            return InvokerHelper.getMethodPointer(object, methodName);
377        }
378    
379        // Coercions
380        //-------------------------------------------------------------------------
381        public static Iterator asIterator(Object collection) throws Throwable {
382            try {
383                return InvokerHelper.asIterator(collection);
384            } catch (GroovyRuntimeException gre) {
385                return (Iterator) unwrap(gre);
386            }
387        }    
388        
389        public static boolean asBool(Object object) throws Throwable {
390            try {
391                return InvokerHelper.asBool(object);
392            } catch (GroovyRuntimeException gre) {
393                unwrap(gre);
394                //return never reached
395                return false;
396            }
397        }
398        
399        public static boolean notBoolean(boolean bool) {
400            return !bool;
401        }    
402        
403        public static boolean notObject(Object object) throws Throwable {
404            return !asBool(object);
405        }
406        
407        public static Pattern regexPattern(Object regex) throws Throwable {
408            try {
409                return InvokerHelper.regexPattern(regex);
410            } catch (GroovyRuntimeException gre) {
411                return (Pattern) unwrap(gre);
412            }
413        }
414        
415        public static Object spreadList(Object value) throws Throwable {
416            try {
417                return InvokerHelper.spreadList(value);
418            } catch (GroovyRuntimeException gre) {
419                return unwrap(gre);
420            }
421        }
422    
423        public static Object spreadMap(Object value) throws Throwable {
424            try {
425                return InvokerHelper.spreadMap(value);
426            } catch (GroovyRuntimeException gre) {
427                return unwrap(gre);
428            }
429        }
430    
431        public static Object negate(Object value) throws Throwable {
432            try {
433                return InvokerHelper.negate(value);
434            } catch (GroovyRuntimeException gre) {
435                return unwrap(gre);
436            }
437        }
438        
439        public static Object bitNegate(Object value) throws Throwable {
440            try {
441                return InvokerHelper.bitNegate(value);
442            } catch (GroovyRuntimeException gre) {
443                return unwrap(gre);
444            }
445        }
446        
447        /**
448         * @param a    array of primitives
449         * @param type component type of the array
450         * @return
451         * @throws Throwable 
452         */
453        public static Object[] convertPrimitiveArray(Object a, Class type) throws Throwable {
454            try {
455                return InvokerHelper.convertPrimitiveArray(a,type);
456            } catch (GroovyRuntimeException gre) {
457                return (Object[])unwrap(gre);
458            }
459        }
460        
461        public static Object convertToPrimitiveArray(Object a, Class type) throws Throwable {
462            try {
463                return InvokerHelper.convertToPrimitiveArray(a,type);
464            } catch (GroovyRuntimeException gre) {
465                return unwrap(gre);
466            }
467        }
468    
469        public static boolean compareIdentical(Object left, Object right) {
470            return left == right;
471        }
472        
473        public static boolean compareEqual(Object left, Object right) throws Throwable{
474            try {
475                return InvokerHelper.compareEqual(left, right);
476            } catch (GroovyRuntimeException gre) {
477                unwrap(gre);
478                // return never reached
479                return false;
480            }
481        }
482        
483        public static boolean compareNotEqual(Object left, Object right) throws Throwable{
484            return !compareEqual(left, right);
485        }
486        
487        public static Integer compareTo(Object left, Object right) throws Throwable{
488            try {
489                return InvokerHelper.compareTo(left, right);
490            } catch (GroovyRuntimeException gre) {
491                return (Integer) unwrap(gre);
492            }
493        }    
494    
495        public static Matcher findRegex(Object left, Object right) throws Throwable{
496            try {
497                return InvokerHelper.findRegex(left, right);
498            } catch (GroovyRuntimeException gre) {
499                return (Matcher) unwrap(gre);
500            }
501        }
502        
503        public static boolean matchRegex(Object left, Object right) throws Throwable{
504            try {
505                return InvokerHelper.matchRegex(left, right);
506            } catch (GroovyRuntimeException gre) {
507                unwrap(gre);
508                // return never reached
509                return false;
510            }
511        }
512    
513        public static boolean compareLessThan(Object left, Object right) throws Throwable{
514            return compareTo(left, right).intValue() < 0;
515        }
516        
517        public static boolean compareLessThanEqual(Object left, Object right) throws Throwable{
518            return compareTo(left, right).intValue() <= 0;
519        }
520        
521        public static boolean compareGreaterThan(Object left, Object right) throws Throwable{
522            return compareTo(left, right).intValue() > 0;
523        }
524    
525        public static boolean compareGreaterThanEqual(Object left, Object right) throws Throwable{
526            return compareTo(left, right).intValue() >= 0;
527        }
528        
529        public static boolean isCase(Object switchValue, Object caseExpression) throws Throwable{
530            return asBool(invokeMethod(caseExpression, "isCase", new Object[]{switchValue}));
531        }
532        
533        public static Tuple createTuple(Object[] array) throws Throwable{
534            return new Tuple(array);
535        }
536    
537        public static List createList(Object[] values) throws Throwable{
538            return InvokerHelper.createList(values);
539        }
540    
541        public static Map createMap(Object[] values) throws Throwable{
542            return InvokerHelper.createMap(values);
543        }
544        
545        public static List createRange(Object from, Object to, boolean inclusive) throws Throwable{
546            try {
547                return InvokerHelper.createRange(from,to,inclusive);
548            } catch (GroovyRuntimeException gre) {
549                return (List) unwrap(gre);
550            }
551        }
552        
553        public static void assertFailed(Object expression, Object message) {
554            InvokerHelper.assertFailed(expression,message);
555        }
556        
557        public static Object box(boolean value) {
558            return value ? Boolean.TRUE : Boolean.FALSE;
559        }
560    
561        public static Object box(byte value) {
562            return new Byte(value);
563        }
564    
565        public static Object box(char value) {
566            return new Character(value);
567        }
568    
569        public static Object box(short value) {
570            return new Short(value);
571        }
572    
573        public static Object box(int value) {
574            return integerValue(value);
575        }
576    
577        public static Object box(long value) {
578            return new Long(value);
579        }
580    
581        public static Object box(float value) {
582            return new Float(value);
583        }
584    
585        public static Object box(double value) {
586            return new Double(value);
587        }
588        
589        /**
590         * get the Integer object from an int. Cached version is used for small ints.
591         *
592         * @param v
593         * @return
594         */
595        public static Integer integerValue(int v) {
596            return InvokerHelper.integerValue(v);
597        }    
598    
599        public static byte byteUnbox(Object value) throws Throwable {
600            Number n = (Number) asType(value, Byte.class);
601            return n.byteValue();
602        }
603    
604        public static char charUnbox(Object value) throws Throwable {
605            Character n = (Character) asType(value, Character.class);
606            return n.charValue();
607        }
608    
609        public static short shortUnbox(Object value) throws Throwable {
610            Number n = (Number) asType(value, Short.class);
611            return n.shortValue();
612        }
613    
614        public static int intUnbox(Object value) throws Throwable {
615            Number n = (Number) asType(value, Integer.class);
616            return n.intValue();
617        }
618    
619        public static boolean booleanUnbox(Object value) throws Throwable {
620            Boolean n = (Boolean) asType(value, Boolean.class);
621            return n.booleanValue();
622        }
623    
624        public static long longUnbox(Object value) throws Throwable {
625            Number n = (Number) asType(value, Long.class);
626            return n.longValue();
627        }
628    
629        public static float floatUnbox(Object value) throws Throwable {
630            Number n = (Number) asType(value, Float.class);
631            return n.floatValue();
632        }
633    
634        public static double doubleUnbox(Object value) throws Throwable {
635            Number n = (Number) asType(value, Double.class);
636            return n.doubleValue();
637        }    
638        
639        public static MetaClass getMetaClass(Object object) {
640            return InvokerHelper.getMetaClass(object);
641        }
642    
643        /*
644        public static void removeClass(Class clazz) {
645            getInstance().removeMetaClass(clazz);
646            Introspector.flushFromCaches(clazz);
647        }
648    
649        public static Invoker getInstance() {
650            return singleton;
651        }
652    
653        public static Collection asCollection(Object collection) {
654            return getInstance().asCollection(collection);
655        }
656    
657        public static List asList(Object args) {
658            return getInstance().asList(args);
659        }
660    
661        public static String toString(Object arguments) {
662            return getInstance().toString(arguments);
663        }
664    
665        public static String toTypeString(Object[] arguments) {
666            return getInstance().toTypeString(arguments);
667        }
668    
669        public static String inspect(Object self) {
670            return getInstance().inspect(self);
671        }
672    
673    
674    
675        public static Object runScript(Class scriptClass, String[] args) {
676            Binding context = new Binding(args);
677            Script script = createScript(scriptClass, context);
678            return invokeMethod(script, "run", EMPTY_ARGS);
679        }
680    
681        public static Script createScript(Class scriptClass, Binding context) {
682            try {
683                final GroovyObject object = (GroovyObject) scriptClass.newInstance();
684                Script script = null;
685                if (object instanceof Script) {
686                    script = (Script) object;
687                } else {
688                    // it could just be a class, so lets wrap it in a Script wrapper
689                    // though the bindings will be ignored
690                    script = new Script() {
691                        public Object run() {
692                            object.invokeMethod("main", EMPTY_MAIN_ARGS);
693                            return null;
694                        }
695                    };
696                    setProperties(object, context.getVariables());
697                }
698                script.setBinding(context);
699                return script;
700            } catch (Exception e) {
701                throw new GroovyRuntimeException("Failed to create Script instance for class: " + scriptClass + ". Reason: " + e,
702                        e);
703            }
704        }
705    */
706        
707        /**
708         * Sets the properties on the given object
709         *
710         * @param object
711         * @param map
712         */
713    /*    public static void setProperties(Object object, Map map) {
714            getMetaClass(object).setProperties(object, map);
715        }
716    
717        public static String getVersion() {
718            String version = null;
719            Package p = Package.getPackage("groovy.lang");
720            if (p != null) {
721                version = p.getImplementationVersion();
722            }
723            if (version == null) {
724                version = "";
725            }
726            return version;
727        }*/
728    
729        /**
730         * Allows conversion of arrays into a mutable List
731         *
732         * @return the array as a List
733         */
734        /*protected static List primitiveArrayToList(Object array) {
735            int size = Array.getLength(array);
736            List list = new ArrayList(size);
737            for (int i = 0; i < size; i++) {
738                list.add(Array.get(array, i));
739            }
740            return list;
741        }*/
742    
743        /**
744         * Writes the given object to the given stream
745         */
746    /*    public static void write(Writer out, Object object) throws IOException {
747            if (object instanceof String) {
748                out.write((String) object);
749            } else if (object instanceof Writable) {
750                Writable writable = (Writable) object;
751                writable.writeTo(out);
752            } else if (object instanceof InputStream || object instanceof Reader) {
753                // Copy stream to stream
754                Reader reader;
755                if (object instanceof InputStream) {
756                    reader = new InputStreamReader((InputStream) object);
757                } else {
758                    reader = (Reader) object;
759                }
760                char[] chars = new char[8192];
761                int i;
762                while ((i = reader.read(chars)) != -1) {
763                    out.write(chars, 0, i);
764                }
765                reader.close();
766            } else {
767                out.write(toString(object));
768            }
769        }
770    
771        public static int[] convertToIntArray(Object a) {
772            int[] ans = null;
773    
774            // conservative coding
775            if (a.getClass().getName().equals("[I")) {
776                ans = (int[]) a;
777            } else {
778                Object[] ia = (Object[]) a;
779                ans = new int[ia.length];
780                for (int i = 0; i < ia.length; i++) {
781                    ans[i] = ((Number) ia[i]).intValue();
782                }
783            }
784            return ans;
785        }
786    
787        public static boolean[] convertToBooleanArray(Object a) {
788            boolean[] ans = null;
789    
790            // conservative coding
791            if (a.getClass().getName().equals("[Z")) {
792                ans = (boolean[]) a;
793            } else {
794                Object[] ia = (Object[]) a;
795                ans = new boolean[ia.length];
796                for (int i = 0; i < ia.length; i++) {
797                    ans[i] = ((Boolean) ia[i]).booleanValue();
798                }
799            }
800            return ans;
801        }
802    
803        public static byte[] convertToByteArray(Object a) {
804            byte[] ans = null;
805    
806            // conservative coding
807            if (a.getClass().getName().equals("[B")) {
808                ans = (byte[]) a;
809            } else {
810                Object[] ia = (Object[]) a;
811                ans = new byte[ia.length];
812                for (int i = 0; i < ia.length; i++) {
813                    if (ia[i] != null)
814                        ans[i] = ((Number) ia[i]).byteValue();
815                }
816            }
817            return ans;
818        }
819    
820        public static short[] convertToShortArray(Object a) {
821            short[] ans = null;
822    
823            // conservative coding
824            if (a.getClass().getName().equals("[S")) {
825                ans = (short[]) a;
826            } else {
827                Object[] ia = (Object[]) a;
828                ans = new short[ia.length];
829                for (int i = 0; i < ia.length; i++) {
830                    ans[i] = ((Number) ia[i]).shortValue();
831                }
832            }
833            return ans;
834        }
835    
836        public static char[] convertToCharArray(Object a) {
837            char[] ans = null;
838    
839            // conservative coding
840            if (a.getClass().getName().equals("[C")) {
841                ans = (char[]) a;
842            } else {
843                Object[] ia = (Object[]) a;
844                ans = new char[ia.length];
845                for (int i = 0; i < ia.length; i++) {
846                    ans[i] = ((Character) ia[i]).charValue();
847                }
848            }
849            return ans;
850        }
851    
852        public static long[] convertToLongArray(Object a) {
853            long[] ans = null;
854    
855            // conservative coding
856            if (a.getClass().getName().equals("[J")) {
857                ans = (long[]) a;
858            } else {
859                Object[] ia = (Object[]) a;
860                ans = new long[ia.length];
861                for (int i = 0; i < ia.length; i++) {
862                    ans[i] = ((Number) ia[i]).longValue();
863                }
864            }
865            return ans;
866        }
867    
868        public static float[] convertToFloatArray(Object a) {
869            float[] ans = null;
870    
871            // conservative coding
872            if (a.getClass().getName().equals("[F")) {
873                ans = (float[]) a;
874            } else {
875                Object[] ia = (Object[]) a;
876                ans = new float[ia.length];
877                for (int i = 0; i < ia.length; i++) {
878                    ans[i] = ((Number) ia[i]).floatValue();
879                }
880            }
881            return ans;
882        }
883    
884        public static double[] convertToDoubleArray(Object a) {
885            double[] ans = null;
886    
887            // conservative coding
888            if (a.getClass().getName().equals("[D")) {
889                ans = (double[]) a;
890            } else {
891                Object[] ia = (Object[]) a;
892                ans = new double[ia.length];
893                for (int i = 0; i < ia.length; i++) {
894                    ans[i] = ((Number) ia[i]).doubleValue();
895                }
896            }
897            return ans;
898        }
899    */
900        
901        /*
902    
903        private static Integer[] SMALL_INTEGERS;
904        private static int INT_CACHE_OFFSET = 128, INT_CACHE_LEN = 256;
905    
906        static {
907            SMALL_INTEGERS = new Integer[INT_CACHE_LEN];
908            for (int i = 0; i < SMALL_INTEGERS.length; i++) {
909                SMALL_INTEGERS[i] = new Integer(i - INT_CACHE_OFFSET);
910            }
911        }*/
912    }