Added ArrayUtil#subarray()
authorkh5325.kim <kh5325.kim@samsung.com>
Mon, 23 Sep 2013 13:29:15 +0000 (22:29 +0900)
committerkh5325.kim <kh5325.kim@samsung.com>
Mon, 23 Sep 2013 13:29:15 +0000 (22:29 +0900)
Change-Id: I23c6efb029cc4d9ad6ba905ddfff3561f2f931a8

org.tizen.common/src/org/tizen/common/util/ArrayUtil.java

index 0d87833..de074f5 100755 (executable)
@@ -41,1120 +41,1152 @@ import java.util.NoSuchElementException;
  */
 public class ArrayUtil
 {
-       /**
-        * Empty {@link Object} array
-        */
-       public static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
-       
+    /**
+     * Empty {@link Object} array
+     */
+    public static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
+    
 
-       /**
-        * <p>
-        * check <code>collection</code> has no element.
-        
-        * use without null check.
-        
-        * Old style
-        
-        * <pre>
-        * Object[] array = null;
-        * ...
-        * if ( null != array && 0 < array.length ) {
-        *  ...
-        * }
-        * </pre>
-        
-        * Usage :
-        * <p>
-        
-        * <pre>
-        * Object[] array = null;
-        * ...
-        * if ( !ArrayUtil.isEmpty( array ) ) {
-        *      ...
-        * }
-        * </pre>
-        
-        * or "import static" style if you use JDK6
-        
-        * </pre>
-        * import static org.tizen.common.util.CollectionUtil.isEmpty;
-        * ...
-        *  
-        * Object[] array = null;
-        * ...
-        * if ( !isEmpty( array ) ) {
-        *      ...
-        * }
-        * </pre>
-        
-        * @param array {@link Collection} to check
-        
-        * @return value if collection is empty
-        */
-       public static <T>
-       boolean
-       isEmpty(
-               final T[] array
-       )
-       {
-               if ( null == array )
-               {
-                       return true;
-               }
-               
-               return (0 == array.length);
-       }
-       
-       /**
-        * <p>
-        * Return first element in <code>array</code><br>
-        
-        * Return <code>null</code> if <code>array</code> is null or empty
-        * </p>
-        
-        * @param <T> type of element in <code>array</code>
-        * @param array object array to check
-        
-        * @return first elemtn in <code>array</code>
-        */
-       public static <T>
-       T
-       pickupFirst( T[] array )
-       {
-               if ( isEmpty( array ) )
-               {
-                       return null;
-               }
-               
-               return array[0];
-       }
+    /**
+     * <p>
+     * check <code>collection</code> has no element.
+     * 
+     * use without null check.
+     * 
+     * Old style
+     * 
+     * <pre>
+     * Object[] array = null;
+     * ...
+     * if ( null != array && 0 < array.length ) {
+     *  ...
+     * }
+     * </pre>
+     * 
+     * Usage :
+     * <p>
+     * 
+     * <pre>
+     * Object[] array = null;
+     * ...
+     * if ( !ArrayUtil.isEmpty( array ) ) {
+     *     ...
+     * }
+     * </pre>
+     * 
+     * or "import static" style if you use JDK6
+     * 
+     * </pre>
+     * import static org.tizen.common.util.CollectionUtil.isEmpty;
+     * ...
+     *  
+     * Object[] array = null;
+     * ...
+     * if ( !isEmpty( array ) ) {
+     *     ...
+     * }
+     * </pre>
+     * 
+     * @param array {@link Collection} to check
+     * 
+     * @return value if collection is empty
+     */
+    public static <T>
+    boolean
+    isEmpty(
+        final T[] array
+    )
+    {
+        if ( null == array )
+        {
+            return true;
+        }
+        
+        return (0 == array.length);
+    }
+    
+    /**
+     * <p>
+     * Return first element in <code>array</code><br>
+     * 
+     * Return <code>null</code> if <code>array</code> is null or empty
+     * </p>
+     * 
+     * @param <T> type of element in <code>array</code>
+     * @param array object array to check
+     * 
+     * @return first elemtn in <code>array</code>
+     */
+    public static <T>
+    T
+    pickupFirst( T[] array )
+    {
+        if ( isEmpty( array ) )
+        {
+            return null;
+        }
+        
+        return array[0];
+    }
 
-       /**
-        * <p>
-        * Return last element in <code>array</code><br>
-        
-        * Return <code>null</code> if <code>array</code> is null or empty
-        * </p>
-        
-        * @param <T> type of element in <code>array</code>
-        * @param array object array to check
-        
-        * @return last elemtn in <code>array</code>
-        */
-       public static <T>
-       T
-       pickupLast( T[] array )
-       {
-               if ( isEmpty( array ) )
-               {
-                       return null;
-               }
-               
-               return array[array.length - 1];
-       }
-       
-       /**
-        * Create array with <code>length</code>
-        
-        * @param <T> type of element in array to create
-        * @param type {@link Class}
-        * @param length array size
-        
-        * @return created array
-        */
-       @SuppressWarnings("unchecked")
-       public static <T>
-       T[] newArray( Class<? extends T> type, int length)
-       {
-               return (T[]) Array.newInstance( type, length);
-       }
+    /**
+     * <p>
+     * Return last element in <code>array</code><br>
+     * 
+     * Return <code>null</code> if <code>array</code> is null or empty
+     * </p>
+     * 
+     * @param <T> type of element in <code>array</code>
+     * @param array object array to check
+     * 
+     * @return last elemtn in <code>array</code>
+     */
+    public static <T>
+    T
+    pickupLast( T[] array )
+    {
+        if ( isEmpty( array ) )
+        {
+            return null;
+        }
+        
+        return array[array.length - 1];
+    }
+    
+    /**
+     * Create array with <code>length</code>
+     * 
+     * @param <T> type of element in array to create
+     * @param type {@link Class}
+     * @param length array size
+     * 
+     * @return created array
+     */
+    @SuppressWarnings("unchecked")
+    public static <T>
+    T[] newArray( Class<? extends T> type, int length)
+    {
+        return (T[]) Array.newInstance( type, length);
+    }
 
-       /**
-        * {@link Iterator} for array
-        *
-        * @param <K> element type in array
-        */
-       public static class
-       ArrayIterator<K>
-       implements Iterator<K>
-       {
-               /**
-                * cloned array
-                */
-               protected final K[] objs;
+    /**
+     * {@link Iterator} for array
+     *
+     * @param <K> element type in array
+     */
+    public static class
+    ArrayIterator<K>
+    implements Iterator<K>
+    {
+        /**
+         * cloned array
+         */
+        protected final K[] objs;
 
-               /**
-                * original array
-                */
-               protected final K[] origin;
+        /**
+         * original array
+         */
+        protected final K[] origin;
 
-               /**
-                * current element index
-                */
-               protected int index = 0;
-               
-               /**
-                * Constructor with array
-                
-                * @param objs array to iterate
-                */
-               public
-               ArrayIterator(
-                       final K[] objs
-               )
-               {
-                       this.origin = objs;
-                       
-                       this.objs = ( null == origin )?null:origin.clone();
-               }
+        /**
+         * current element index
+         */
+        protected int index = 0;
+        
+        /**
+         * Constructor with array
+         * 
+         * @param objs array to iterate
+         */
+        public
+        ArrayIterator(
+            final K[] objs
+        )
+        {
+            this.origin = objs;
+            
+            this.objs = ( null == origin )?null:origin.clone();
+        }
 
-               /* (non-Javadoc)
-                * @see java.util.Iterator#hasNext()
-                */
-               @Override
-               public
-               boolean
-               hasNext()
-               {
-                       if ( null == this.objs )
-                       {
-                               return false;
-                       }
-                       return ( index < this.objs.length );
-               }
+        /* (non-Javadoc)
+         * @see java.util.Iterator#hasNext()
+         */
+        @Override
+        public
+        boolean
+        hasNext()
+        {
+            if ( null == this.objs )
+            {
+                return false;
+            }
+            return ( index < this.objs.length );
+        }
 
-               /* (non-Javadoc)
-                * @see java.util.Iterator#next()
-                */
-               @Override
-               public
-               K
-               next()
-               {
-                       if ( null == this.objs )
-                       {
-                               throw new NoSuchElementException();
-                       }
-                       if ( this.objs.length <= index  )
-                       {
-                               throw new NoSuchElementException();
-                       }
-                       
-                       if ( objs[index] != origin[index] ) {
-                               throw new ConcurrentModificationException();
-                       }
-                       return this.objs[index++];
-               }
+        /* (non-Javadoc)
+         * @see java.util.Iterator#next()
+         */
+        @Override
+        public
+        K
+        next()
+        {
+            if ( null == this.objs )
+            {
+                throw new NoSuchElementException();
+            }
+            if ( this.objs.length <= index  )
+            {
+                throw new NoSuchElementException();
+            }
+            
+            if ( objs[index] != origin[index] ) {
+                throw new ConcurrentModificationException();
+            }
+            return this.objs[index++];
+        }
 
-               /* (non-Javadoc)
-                * @see java.util.Iterator#remove()
-                */
-               @Override
-               public
-               void
-               remove()
-               {
-                       throw new UnsupportedOperationException();
-               }
+        /* (non-Javadoc)
+         * @see java.util.Iterator#remove()
+         */
+        @Override
+        public
+        void
+        remove()
+        {
+            throw new UnsupportedOperationException();
+        }
 
-       }
-       
-       /**
-        * Create and return {@link Iterator} for <code>array</code>
-        
-        * @param <T> iteraing element's type
-        * @param array array to iterate
-        
-        * @return {@link Iterator} for <code>array</code>
-        */
-       public static <T> Iterator<T> iterator( final T[] array )
-       {
-               return new ArrayIterator<T>( array );
-       }
-       
-       /**
-        * <p>
-        * run <code>runner</code> iterateing element of <code>array</code>.
-        
-        * use without null-check for <code>array</code>
-        
-        * delegate error handling to <code>array</code>
-        * </p>
-        
-        * <pre>
-        
-        * ArrayUtil.iterate(
-        *      Arrays.asList( "hello", "Hello", "World", null, "Test" ),
-        *      new IteratingRunner<String>() {
-        *              public void run( String arg ) {
-        *                      ...
-        *              }
-        *      }
-        * );
-        
-        * </pre>
-        
-        * @param <T> type of element in <code>array</code>
-        * @param array array containing element
-        * @param runner {@link Runnable} to execute
-        
-        * @throws InvocationTargetException when <code>runner</code>'s {@link Runnable#run()} throws exception 
-        
-        * @see {@link #iterate(Object[], IteratingRunner, boolean)}
-        * @see FilterIterator
-        */
-       public static <T>
-       void
-       iterate(
-               final T[] array,
-               final IteratingRunner<T> runner
-       )
-       {
-               try
-               {
-                       iterate( array, runner, true );
-               } catch ( final InvocationTargetException e)
-               {
-                       // Be never reached
-                       throw new IllegalStateException( e );
-               }
-       }
-       
-       /**
-        * <p>
-        * run <code>runner</code> iterateing element of <code>array</code>.
-        
-        * use without null-check for <code>array</code>
-        
-        * delegate error handling to <code>runner</code>
-        
-        * </p>
-        * <pre>
-        
-        * ArrayUtil.iterate(
-        *      Arrays.asList( "hello", "Hello", "World", null, "Test" ),
-        *      new IteratingRunner<String>() {
-        *              public void run( String arg ) {
-        *                      ...
-        *              }
-        *      },
-        *      true
-        * );
-        
-        * </pre>
-        
-        * @param <T> type of element in <code>array</code>
-        * @param array array containing element
-        * @param runner {@link Runnable} to execute
-        * @param bForceProcess flag to iterate continuously when exception occurs
-        
-        * @throws InvocationTargetException when <code>runner</code>'s {@link Runnable#run()} throws exception 
-        
-        * @see FilterIterator
-        */
-       public static <T>
-       void
-       iterate(
-               final T[] array,
-               final IteratingRunner<T> runner,
-               final boolean bForceProcess
-       )
-       throws InvocationTargetException
-       {
-               if ( null == runner )
-               {
-                       return ;
-               }
-               
-               for ( final T arg : safe( array ) )
-               {
-                       if ( null == arg && !bForceProcess )
-                       {
-                               continue ;
-                       }
-                       try
-                       {
-                               runner.run( arg );
-                       } catch ( Throwable e )
-                       {
-                               if ( !bForceProcess )
-                               {
-                                       throw new InvocationTargetException( e );
-                               }
-                       }
-               }
-       }
-       
-       /**
-        * <p>
-        * Fiter <code>array</code> and return filtered array
-        
-        * Ignore exception in filtering logic
-        * </p>
-        
-        * @param <T> type of element in <code>array</code>
-        * @param array array to filter
-        * @param runner object to determine if filter
-        */
-       public static <T>
-       T[]
-       filter(
-               final T[] array,
-               final IteratingAcceptor<T> runner
-       )
-       {
-               try
-               {
-                       return filter( array, runner, true );
-               } catch ( final InvocationTargetException e )
-               {
-                       // Be never reached
-                       throw new IllegalStateException( e );
-               }
-       }
-       /**
-        * <p>
-        * Fiter <code>array</code> and return filtered array
-        
-        * determined if stop or keep going using <code>bForceProcess</code> in case of exception.
-        * </p>
-        
-        * @param <T> type of element in <code>array</code>
-        * @param array array to filter
-        * @param runner object to determine if filter
-        * @param bForceProcess flag to keep going when exception occurs
-        
-        * @throws InvocationTargetException when <code>runner</code>'s {@link IteratingAcceptor#accept(Object)} throws exception 
-        */
-       @SuppressWarnings("unchecked")
-       public static <T>
-       T[]
-       filter(
-               final T[] array,
-               final IteratingAcceptor<T> runner,
-               final boolean bForceProcess
-       ) throws InvocationTargetException
-       {
-               final ArrayList<T> list = new ArrayList<T>();
-               
-               for ( final T arg : safe( array ) )
-               {
-                       if ( null == arg && !bForceProcess )
-                       {
-                               continue ;
-                       }
-                       try
-                       {
-                               if ( runner.accept( arg ) )
-                               {
-                                       list.add( arg );
-                               }
-                       } catch ( Throwable e )
-                       {
-                               if ( !bForceProcess )
-                               {
-                                       throw new InvocationTargetException( e );
-                               }
-                       }
+    }
+    
+    /**
+     * Create and return {@link Iterator} for <code>array</code>
+     * 
+     * @param <T> iteraing element's type
+     * @param array array to iterate
+     * 
+     * @return {@link Iterator} for <code>array</code>
+     */
+    public static <T> Iterator<T> iterator( final T[] array )
+    {
+        return new ArrayIterator<T>( array );
+    }
+    
+    /**
+     * <p>
+     * run <code>runner</code> iterateing element of <code>array</code>.
+     * 
+     * use without null-check for <code>array</code>
+     * 
+     * delegate error handling to <code>array</code>
+     * </p>
+     * 
+     * <pre>
+     * 
+     * ArrayUtil.iterate(
+     *     Arrays.asList( "hello", "Hello", "World", null, "Test" ),
+     *     new IteratingRunner<String>() {
+     *         public void run( String arg ) {
+     *             ...
+     *         }
+     *     }
+     * );
+     * 
+     * </pre>
+     * 
+     * @param <T> type of element in <code>array</code>
+     * @param array array containing element
+     * @param runner {@link Runnable} to execute
+     * 
+     * @throws InvocationTargetException when <code>runner</code>'s {@link Runnable#run()} throws exception 
+     * 
+     * @see {@link #iterate(Object[], IteratingRunner, boolean)}
+     * @see FilterIterator
+     */
+    public static <T>
+    void
+    iterate(
+        final T[] array,
+        final IteratingRunner<T> runner
+    )
+    {
+        try
+        {
+            iterate( array, runner, true );
+        } catch ( final InvocationTargetException e)
+        {
+            // Be never reached
+            throw new IllegalStateException( e );
+        }
+    }
+    
+    /**
+     * <p>
+     * run <code>runner</code> iterateing element of <code>array</code>.
+     * 
+     * use without null-check for <code>array</code>
+     * 
+     * delegate error handling to <code>runner</code>
+     * 
+     * </p>
+     * <pre>
+     * 
+     * ArrayUtil.iterate(
+     *     Arrays.asList( "hello", "Hello", "World", null, "Test" ),
+     *     new IteratingRunner<String>() {
+     *         public void run( String arg ) {
+     *             ...
+     *         }
+     *     },
+     *     true
+     * );
+     * 
+     * </pre>
+     * 
+     * @param <T> type of element in <code>array</code>
+     * @param array array containing element
+     * @param runner {@link Runnable} to execute
+     * @param bForceProcess flag to iterate continuously when exception occurs
+     * 
+     * @throws InvocationTargetException when <code>runner</code>'s {@link Runnable#run()} throws exception 
+     * 
+     * @see FilterIterator
+     */
+    public static <T>
+    void
+    iterate(
+        final T[] array,
+        final IteratingRunner<T> runner,
+        final boolean bForceProcess
+    )
+    throws InvocationTargetException
+    {
+        if ( null == runner )
+        {
+            return ;
+        }
+        
+        for ( final T arg : safe( array ) )
+        {
+            if ( null == arg && !bForceProcess )
+            {
+                continue ;
+            }
+            try
+            {
+                runner.run( arg );
+            } catch ( Throwable e )
+            {
+                if ( !bForceProcess )
+                {
+                    throw new InvocationTargetException( e );
+                }
+            }
+        }
+    }
+    
+    /**
+     * <p>
+     * Fiter <code>array</code> and return filtered array
+     * 
+     * Ignore exception in filtering logic
+     * </p>
+     * 
+     * @param <T> type of element in <code>array</code>
+     * @param array array to filter
+     * @param runner object to determine if filter
+     */
+    public static <T>
+    T[]
+    filter(
+        final T[] array,
+        final IteratingAcceptor<T> runner
+    )
+    {
+        try
+        {
+            return filter( array, runner, true );
+        } catch ( final InvocationTargetException e )
+        {
+            // Be never reached
+            throw new IllegalStateException( e );
+        }
+    }
+    /**
+     * <p>
+     * Fiter <code>array</code> and return filtered array
+     * 
+     * determined if stop or keep going using <code>bForceProcess</code> in case of exception.
+     * </p>
+     * 
+     * @param <T> type of element in <code>array</code>
+     * @param array array to filter
+     * @param runner object to determine if filter
+     * @param bForceProcess flag to keep going when exception occurs
+     * 
+     * @throws InvocationTargetException when <code>runner</code>'s {@link IteratingAcceptor#accept(Object)} throws exception 
+     */
+    @SuppressWarnings("unchecked")
+    public static <T>
+    T[]
+    filter(
+        final T[] array,
+        final IteratingAcceptor<T> runner,
+        final boolean bForceProcess
+    ) throws InvocationTargetException
+    {
+        final ArrayList<T> list = new ArrayList<T>();
+        
+        for ( final T arg : safe( array ) )
+        {
+            if ( null == arg && !bForceProcess )
+            {
+                continue ;
+            }
+            try
+            {
+                if ( runner.accept( arg ) )
+                {
+                    list.add( arg );
+                }
+            } catch ( Throwable e )
+            {
+                if ( !bForceProcess )
+                {
+                    throw new InvocationTargetException( e );
+                }
+            }
 
-               }
-               
-               return (T[]) list.toArray( newArray( array.getClass().getComponentType(), list.size() ) );
-       }
+        }
+        
+        return (T[]) list.toArray( newArray( array.getClass().getComponentType(), list.size() ) );
+    }
 
-       
-       /**
-        * Convert <code>source</code> to {@link Object[]}
-        
-        * throw {@link IllegalArgumentException} if source is not array type
-        
-        * @param source object to convert 
-        
-        * @return object to converted
-        */
-       public static
-       Object[]
-       toObjectArray(
-               final Object source
-       )
-       {
-               if ( source instanceof Object[] )
-               {
-                       return ( Object[] )source; 
-               }
+    
+    /**
+     * Convert <code>source</code> to {@link Object[]}
+     * 
+     * throw {@link IllegalArgumentException} if source is not array type
+     * 
+     * @param source object to convert 
+     * 
+     * @return object to converted
+     */
+    public static
+    Object[]
+    toObjectArray(
+        final Object source
+    )
+    {
+        if ( source instanceof Object[] )
+        {
+            return ( Object[] )source; 
+        }
 
-               if ( null == source )
-               {
-                       return EMPTY_OBJECT_ARRAY; 
-               }
-               
-               if ( !source.getClass().isArray() )
-               {
-                       throw new IllegalArgumentException( "source must be an array");
-               }
+        if ( null == source )
+        {
+            return EMPTY_OBJECT_ARRAY; 
+        }
+        
+        if ( !source.getClass().isArray() )
+        {
+            throw new IllegalArgumentException( "source must be an array");
+        }
 
-               final int length = Array.getLength( source );
-               if ( 0 == length )
-               {
-                       return EMPTY_OBJECT_ARRAY; 
-               }
-               
-               Class<?> wrapperType = null;
-               for ( int i = 0 ; null == wrapperType && i < length ; ++i )
-               {
-                       Object obj = Array.get( source, 0 );
-                       if ( null == obj )
-                       {
-                               continue;
-                       }
-                       wrapperType = obj.getClass();
-               }
-               if ( null == wrapperType )
-               {
-                       return (Object[]) source;
-               }
-               
-               final Object[] newArray =
-                       (Object[]) Array.newInstance( wrapperType, length );
-               for( int i=0 ; i<length ; ++i )
-               {
-                       newArray[i] = Array.get( source, i );
-               }
-               
-               return newArray;
-       }
-       
-       /**
-        * Return size if object is array or {@link Collection}
-        
-        * Return <code>0</code> in case of the other type
-        
-        * @param obj object to check
-        
-        * @return size
-        */
-       public static
-       int
-       size(
-               final Object obj
-       )
-       {
-               if ( obj instanceof Object[] )
-               {
-                       return size( ( Object[] ) obj );
-               }
-               else if ( obj instanceof boolean[] )
-               {
-                       return size( ( boolean[] ) obj );
-               }
-               else if ( obj instanceof byte[] )
-               {
-                       return size( ( byte[] )obj );
-               }
-               else if ( obj instanceof char[] )
-               {
-                       return size( ( char[] ) obj );
-               }
-               else if ( obj instanceof short[] )
-               {
-                       return size( ( short[] )obj );
-               }
-               else if ( obj instanceof int[] )
-               {
-                       return size( (int[] ) obj );
-               }
-               else if ( obj instanceof long[] )
-               {
-                       return size( ( long[] ) obj );
-               }
-               else if ( obj instanceof float[] )
-               {
-                       return size( (float[] ) obj );
-               }
-               else if ( obj instanceof double[] )
-               {
-                       return size( ( double[] ) obj );
-               }
-               else if ( obj instanceof Collection )
-               {
-                       return CollectionUtil.size( (Collection<?>) obj );
-               }
-               return 0;
-       
-       }
+        final int length = Array.getLength( source );
+        if ( 0 == length )
+        {
+            return EMPTY_OBJECT_ARRAY; 
+        }
+        
+        Class<?> wrapperType = null;
+        for ( int i = 0 ; null == wrapperType && i < length ; ++i )
+        {
+            Object obj = Array.get( source, 0 );
+            if ( null == obj )
+            {
+                continue;
+            }
+            wrapperType = obj.getClass();
+        }
+        if ( null == wrapperType )
+        {
+            return (Object[]) source;
+        }
+        
+        final Object[] newArray =
+            (Object[]) Array.newInstance( wrapperType, length );
+        for( int i=0 ; i<length ; ++i )
+        {
+            newArray[i] = Array.get( source, i );
+        }
+        
+        return newArray;
+    }
+    
+    /**
+     * Return size if object is array or {@link Collection}
+     * 
+     * Return <code>0</code> in case of the other type
+     * 
+     * @param obj object to check
+     * 
+     * @return size
+     */
+    public static
+    int
+    size(
+        final Object obj
+    )
+    {
+        if ( obj instanceof Object[] )
+        {
+            return size( ( Object[] ) obj );
+        }
+        else if ( obj instanceof boolean[] )
+        {
+            return size( ( boolean[] ) obj );
+        }
+        else if ( obj instanceof byte[] )
+        {
+            return size( ( byte[] )obj );
+        }
+        else if ( obj instanceof char[] )
+        {
+            return size( ( char[] ) obj );
+        }
+        else if ( obj instanceof short[] )
+        {
+            return size( ( short[] )obj );
+        }
+        else if ( obj instanceof int[] )
+        {
+            return size( (int[] ) obj );
+        }
+        else if ( obj instanceof long[] )
+        {
+            return size( ( long[] ) obj );
+        }
+        else if ( obj instanceof float[] )
+        {
+            return size( (float[] ) obj );
+        }
+        else if ( obj instanceof double[] )
+        {
+            return size( ( double[] ) obj );
+        }
+        else if ( obj instanceof Collection )
+        {
+            return CollectionUtil.size( (Collection<?>) obj );
+        }
+        return 0;
+    
+    }
 
-       /**
-        * Return <code>objs</code>'s length
-        
-        * Return 0 if <code>objs</code> is null.
-        
-        * @param objs boolean array object
-        
-        * @return size of array
-        */
-       public static
-       int
-       size(
-               final boolean[] objs
-       ) {
-               if ( null == objs )
-               {
-                       return 0;
-               }
-               return objs.length;
-       }
-       
-       /**
-        * Return <code>objs</code>'s length
-        
-        * Return 0 if <code>objs</code> is null.
-        
-        * @param objs byte array object
-        
-        * @return size of array
-        */
-       public static
-       int
-       size(
-               final byte[] objs
-       ) {
-               if ( null == objs )
-               {
-                       return 0;
-               }
-               return objs.length;
-       }
-       
-       
-       /**
-        * Return <code>objs</code>'s length
-        
-        * Return 0 if <code>objs</code> is null.
-        
-        * @param objs char array object
-        
-        * @return size of array
-        */
-       public static
-       int
-       size(
-               final char[] objs
-       ) {
-               if ( null == objs )
-               {
-                       return 0;
-               }
-               return objs.length;
-       }
-       
-       /**
-        * Return <code>objs</code>'s length
-        
-        * Return 0 if <code>objs</code> is null.
-        
-        * @param objs short array object
-        
-        * @return size of array
-        */
-       public static
-       int
-       size(
-               final short[] objs
-       ) {
-               if ( null == objs )
-               {
-                       return 0;
-               }
-               return objs.length;
-       }
-       
-       /**
-        * Return <code>objs</code>'s length
-        
-        * Return 0 if <code>objs</code> is null.
-        
-        * @param objs int array object
-        
-        * @return size of array
-        */
-       public static
-       int
-       size(
-               final int[] objs
-       ) {
-               if ( null == objs )
-               {
-                       return 0;
-               }
-               return objs.length;
-       }
-       
-       /**
-        * Return <code>objs</code>'s length
-        
-        * Return 0 if <code>objs</code> is null.
-        
-        * @param objs long array object
-        
-        * @return size of array
-        */
-       public static
-       int
-       size(
-               final long[] objs
-       ) {
-               if ( null == objs )
-               {
-                       return 0;
-               }
-               return objs.length;
-       }
-       
-       /**
-        * Return <code>objs</code>'s length
-        
-        * Return 0 if <code>objs</code> is null.
-        
-        * @param objs float array object
-        
-        * @return size of array
-        */
-       public static
-       int
-       size(
-               final float[] objs
-       ) {
-               if ( null == objs )
-               {
-                       return 0;
-               }
-               return objs.length;
-       }
-       
-       /**
-        * Return <code>objs</code>'s length
-        
-        * Return 0 if <code>objs</code> is null.
-        
-        * @param objs double array object
-        
-        * @return size of array
-        */
-       public static
-       int
-       size(
-               final double[] objs
-       ) {
-               if ( null == objs )
-               {
-                       return 0;
-               }
-               return objs.length;
-       }
-       
-       /**
-        * Return <code>objs</code>'s length
-        
-        * Return 0 if <code>objs</code> is null.
-        
-        * @param <T> type of array
-        * @param objs T type array object
-        
-        * @return size of array
-        */
-       public static <T>
-       int
-       size(
-               final T[] objs
-       ) {
-               if ( null == objs )
-               {
-                       return 0;
-               }
-               return objs.length;
-       }
+    /**
+     * Return <code>objs</code>'s length
+     * 
+     * Return 0 if <code>objs</code> is null.
+     * 
+     * @param objs boolean array object
+     * 
+     * @return size of array
+     */
+    public static
+    int
+    size(
+        final boolean[] objs
+    ) {
+        if ( null == objs )
+        {
+            return 0;
+        }
+        return objs.length;
+    }
+    
+    /**
+     * Return <code>objs</code>'s length
+     * 
+     * Return 0 if <code>objs</code> is null.
+     * 
+     * @param objs byte array object
+     * 
+     * @return size of array
+     */
+    public static
+    int
+    size(
+        final byte[] objs
+    ) {
+        if ( null == objs )
+        {
+            return 0;
+        }
+        return objs.length;
+    }
+    
+    
+    /**
+     * Return <code>objs</code>'s length
+     * 
+     * Return 0 if <code>objs</code> is null.
+     * 
+     * @param objs char array object
+     * 
+     * @return size of array
+     */
+    public static
+    int
+    size(
+        final char[] objs
+    ) {
+        if ( null == objs )
+        {
+            return 0;
+        }
+        return objs.length;
+    }
+    
+    /**
+     * Return <code>objs</code>'s length
+     * 
+     * Return 0 if <code>objs</code> is null.
+     * 
+     * @param objs short array object
+     * 
+     * @return size of array
+     */
+    public static
+    int
+    size(
+        final short[] objs
+    ) {
+        if ( null == objs )
+        {
+            return 0;
+        }
+        return objs.length;
+    }
+    
+    /**
+     * Return <code>objs</code>'s length
+     * 
+     * Return 0 if <code>objs</code> is null.
+     * 
+     * @param objs int array object
+     * 
+     * @return size of array
+     */
+    public static
+    int
+    size(
+        final int[] objs
+    ) {
+        if ( null == objs )
+        {
+            return 0;
+        }
+        return objs.length;
+    }
+    
+    /**
+     * Return <code>objs</code>'s length
+     * 
+     * Return 0 if <code>objs</code> is null.
+     * 
+     * @param objs long array object
+     * 
+     * @return size of array
+     */
+    public static
+    int
+    size(
+        final long[] objs
+    ) {
+        if ( null == objs )
+        {
+            return 0;
+        }
+        return objs.length;
+    }
+    
+    /**
+     * Return <code>objs</code>'s length
+     * 
+     * Return 0 if <code>objs</code> is null.
+     * 
+     * @param objs float array object
+     * 
+     * @return size of array
+     */
+    public static
+    int
+    size(
+        final float[] objs
+    ) {
+        if ( null == objs )
+        {
+            return 0;
+        }
+        return objs.length;
+    }
+    
+    /**
+     * Return <code>objs</code>'s length
+     * 
+     * Return 0 if <code>objs</code> is null.
+     * 
+     * @param objs double array object
+     * 
+     * @return size of array
+     */
+    public static
+    int
+    size(
+        final double[] objs
+    ) {
+        if ( null == objs )
+        {
+            return 0;
+        }
+        return objs.length;
+    }
+    
+    /**
+     * Return <code>objs</code>'s length
+     * 
+     * Return 0 if <code>objs</code> is null.
+     * 
+     * @param <T> type of array
+     * @param objs T type array object
+     * 
+     * @return size of array
+     */
+    public static <T>
+    int
+    size(
+        final T[] objs
+    ) {
+        if ( null == objs )
+        {
+            return 0;
+        }
+        return objs.length;
+    }
 
-       /**
-        * add <code>obj</code> to <code>array</code>
-        
-        * Return array having only <code>obj</code> if <code>array</code> is <code>null</code>
-        
-        * @param array array to add element
-        * @param obj new element to add
-        
-        * @return added array
-        */
-       @SuppressWarnings("unchecked")
-       public static <T> T[]
-       add(
-               final T[] array,
-               final T obj
-       )
-       {
-               Class<?> compType = Object.class;
-               if ( null != array )
-               {
-                       compType = array.getClass().getComponentType();
-               }
-               else if ( null != obj )
-               {
-                       compType = obj.getClass();
-               }
+    /**
+     * add <code>obj</code> to <code>array</code>
+     * 
+     * Return array having only <code>obj</code> if <code>array</code> is <code>null</code>
+     * 
+     * @param array array to add element
+     * @param obj new element to add
+     * 
+     * @return added array
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> T[]
+    add(
+        final T[] array,
+        final T obj
+    )
+    {
+        Class<?> compType = Object.class;
+        if ( null != array )
+        {
+            compType = array.getClass().getComponentType();
+        }
+        else if ( null != obj )
+        {
+            compType = obj.getClass();
+        }
 
-               final int newArrLength = size( array ) + 1;
-               final T[] newArr = 
-                       (T[]) Array.newInstance( compType, newArrLength );
-               
-               if ( null != array )
-               {
-                       System.arraycopy( array, 0, newArr, 0, array.length );
-               }
-               newArr[newArrLength - 1] = obj;
-               return newArr;
-       }
+        final int newArrLength = size( array ) + 1;
+        final T[] newArr = 
+            (T[]) Array.newInstance( compType, newArrLength );
+        
+        if ( null != array )
+        {
+            System.arraycopy( array, 0, newArr, 0, array.length );
+        }
+        newArr[newArrLength - 1] = obj;
+        return newArr;
+    }
 
-       /**
-        * prepend <code>obj</code> to <code>array</code>
-        
-        * Return array having only <code>obj</code> if <code>array</code> is <code>null</code>
-        
-        * @param array array to add element
-        * @param obj new element to add
-        
-        * @return added array
-        */
-       @SuppressWarnings("unchecked")
-       public static <T> T[]
-       prepend(
-               final T[] array,
-               final T obj
-       )
-       {
-               Class<?> compType = Object.class;
-               if ( null != array )
-               {
-                       compType = array.getClass().getComponentType();
-               }
-               else if ( null != obj )
-               {
-                       compType = obj.getClass();
-               }
+    /**
+     * prepend <code>obj</code> to <code>array</code>
+     * 
+     * Return array having only <code>obj</code> if <code>array</code> is <code>null</code>
+     * 
+     * @param array array to add element
+     * @param obj new element to add
+     * 
+     * @return added array
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> T[]
+    prepend(
+        final T[] array,
+        final T obj
+    )
+    {
+        Class<?> compType = Object.class;
+        if ( null != array )
+        {
+            compType = array.getClass().getComponentType();
+        }
+        else if ( null != obj )
+        {
+            compType = obj.getClass();
+        }
 
-               final int newArrLength = size( array ) + 1;
-               final T[] newArr = 
-                       (T[]) Array.newInstance( compType, newArrLength );
-               
-               if ( null != array )
-               {
-                       System.arraycopy( array, 0, newArr, 1, array.length );
-               }
-               newArr[0] = obj;
-               return newArr;
-       }
+        final int newArrLength = size( array ) + 1;
+        final T[] newArr = 
+            (T[]) Array.newInstance( compType, newArrLength );
+        
+        if ( null != array )
+        {
+            System.arraycopy( array, 0, newArr, 1, array.length );
+        }
+        newArr[0] = obj;
+        return newArr;
+    }
 
-       /**
-        * remove elements whose index is between <code>startIndex</code> and <code>endIndex</code>
-        
-        * and return applied array
-        
-        * @param <T> type of array element
-        * @param array array to remove elements
-        * @param startIndex start index of range to remove
-        * @param endIndex end index of range to remove
-        
-        * @return change applied new array
-        
-        * @throws ArrayIndexOutOfBoundsException 
-        *              if <code>startIndex</code> or <code>endIndex</code> is not in range of array
-        * @throws IllegalArgumentException
-        *              if <code>startIndex</code> is greater than <code>endIndex</code>
-        */
-       @SuppressWarnings("unchecked")
-       public static <T> T[]
-       remove(
-               final Object[] array,
-               final int start,
-               final int end
-       )
-       {
-           Assert.notNull( array );
-               Assert.isTrue(
-                       start <= end,
-                       "start indnex(" + start + ") is greater than end index(" + end + ")"
-               );
-               
-               int startIndex = Math.max( 0, start );
-               int endIndex = Math.min( array.length, end );
-               if ( endIndex <= startIndex )
-               {
-                       return (T[]) array;
-               }
-               
-               final Class<?> compType = array.getClass().getComponentType();
-               
-               final int removeSize = endIndex - startIndex;
+    /**
+     * remove elements whose index is between <code>startIndex</code> and <code>endIndex</code>
+     * 
+     * and return applied array
+     * 
+     * @param <T> type of array element
+     * @param array array to remove elements
+     * @param startIndex start index of range to remove
+     * @param endIndex end index of range to remove
+     * 
+     * @return change applied new array
+     * 
+     * @throws ArrayIndexOutOfBoundsException 
+     *         if <code>startIndex</code> or <code>endIndex</code> is not in range of array
+     * @throws IllegalArgumentException
+     *         if <code>startIndex</code> is greater than <code>endIndex</code>
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> T[]
+    remove(
+        final Object[] array,
+        final int start,
+        final int end
+    )
+    {
+        Assert.notNull( array );
+        Assert.isTrue(
+            start <= end,
+            "start indnex(" + start + ") is greater than end index(" + end + ")"
+        );
+        
+        int startIndex = Math.max( 0, start );
+        int endIndex = Math.min( array.length, end );
+        if ( endIndex <= startIndex )
+        {
+            return (T[]) array;
+        }
+        
+        final Class<?> compType = array.getClass().getComponentType();
+        
+        final int removeSize = endIndex - startIndex;
 
-               final int newArrLength = size( array ) - removeSize;
-               
-               final Object[] newArr = 
-                       (Object[]) Array.newInstance( compType, newArrLength );
-               
-               System.arraycopy( array, 0, newArr, 0, startIndex );
-               System.arraycopy( array, endIndex, newArr, startIndex, array.length-endIndex );
-               
-               return (T[]) newArr;
-       }
+        final int newArrLength = size( array ) - removeSize;
+        
+        final Object[] newArr = 
+            (Object[]) Array.newInstance( compType, newArrLength );
+        
+        System.arraycopy( array, 0, newArr, 0, startIndex );
+        System.arraycopy( array, endIndex, newArr, startIndex, array.length-endIndex );
+        
+        return (T[]) newArr;
+    }
 
-       /**
-        * remove elements whose index is <code>index</code>
-        
-        * and return applied array
-        *
-        * @param <T> type of array element
-        * @param array array to remove elements
-        * @param index index to remove
-        
-        * @return change applied new array
-        
-        * @throws ArrayIndexOutOfBoundsException 
-        *              if <code>index</code> is not in range of array
-        */
-       public static <T> T[]
-       remove(
-               final Object[] array,
-               final int index
-       )
-       {
-               return remove( array, index, index + 1);
-       }
+    /**
+     * remove elements whose index is <code>index</code>
+     * 
+     * and return applied array
+     *
+     * @param <T> type of array element
+     * @param array array to remove elements
+     * @param index index to remove
+     * 
+     * @return change applied new array
+     * 
+     * @throws ArrayIndexOutOfBoundsException 
+     *         if <code>index</code> is not in range of array
+     */
+    public static <T> T[]
+    remove(
+        final Object[] array,
+        final int index
+    )
+    {
+        return remove( array, index, index + 1);
+    }
 
-       /**
-        * Check if <code>array</code> contains <code>element</code>
-        
-        * @param array array to check
-        * @param element object to check
-        
-        * @return <code>true</code> if <code>collection</code> contain <code>element</code>
-        */
-       public static <K, V>
-       boolean
-       contains(
-               final K[] array,
-               final V element
-       )
-       {
-               if ( null == array )
-               {
-                       return false;
-               }
-               
-               for ( final Object candidate : array )
-               {
-                       if ( ObjectUtil.equals( candidate, element ) )
-                       {
-                               return true; 
-                       }
-               }
-               return false;
-       }
-       
-       /**
-        * Return <code>index</code> th element in <code>collection</code>
-        
-        * Return <code>null</code> if <code>index</code> is out of range
-        
-        * @param <K> array type
-        * @param array array object to access
-        * @param index array index
-        * @return <code>index</code> th element in array
-        */
-       public static <K>
-       K
-       get(
-               final K[] array,
-               final int index
-       )
-       {
-               if ( null == array )
-               {
-                       return null;
-               }
-               if ( index < 0 )
-               {
-                       return null;
-               }
-               if ( array.length <= index )
-               {
-                       return null;
-               }
-               
-               return array[index];
-       }
+    /**
+     * Check if <code>array</code> contains <code>element</code>
+     * 
+     * @param array array to check
+     * @param element object to check
+     * 
+     * @return <code>true</code> if <code>collection</code> contain <code>element</code>
+     */
+    public static <K, V>
+    boolean
+    contains(
+        final K[] array,
+        final V element
+    )
+    {
+        if ( null == array )
+        {
+            return false;
+        }
+        
+        for ( final Object candidate : array )
+        {
+            if ( ObjectUtil.equals( candidate, element ) )
+            {
+                return true; 
+            }
+        }
+        return false;
+    }
+    
+    /**
+     * Return <code>index</code> th element in <code>collection</code>
+     * 
+     * Return <code>null</code> if <code>index</code> is out of range
+     * 
+     * @param <K> array type
+     * @param array array object to access
+     * @param index array index
+     * @return <code>index</code> th element in array
+     */
+    public static <K>
+    K
+    get(
+        final K[] array,
+        final int index
+    )
+    {
+        if ( null == array )
+        {
+            return null;
+        }
+        if ( index < 0 )
+        {
+            return null;
+        }
+        if ( array.length <= index )
+        {
+            return null;
+        }
+        
+        return array[index];
+    }
 
-       /**
-        * Convert <code>array</code> to {@link Boolean[]}
-        
-        * @param array array to convert
-        
-        * @return converted array
-        */
-       public static Boolean[] convertToWrapper( final boolean[] array )
-       {
-               final int nArray = size( array );
-               final Boolean[] ret = new Boolean[nArray];
-               
-               for ( int i = 0 ; i < nArray ; ++i )
-               {
-                       ret[i] = array[i];
-               }
-               
-               return ret;
-       }
+    /**
+     * Convert <code>array</code> to {@link Boolean[]}
+     * 
+     * @param array array to convert
+     * 
+     * @return converted array
+     */
+    public static Boolean[] convertToWrapper( final boolean[] array )
+    {
+        final int nArray = size( array );
+        final Boolean[] ret = new Boolean[nArray];
+        
+        for ( int i = 0 ; i < nArray ; ++i )
+        {
+            ret[i] = array[i];
+        }
+        
+        return ret;
+    }
 
-       /**
-        * Convert <code>array</code> to {@link Byte[]}
-        
-        * @param array array to convert
-        
-        * @return converted array
-        */
-       public static Byte[] convertToWrapper( final byte[] array )
-       {
-               final int nArray = size( array );
-               final Byte[] ret = new Byte[nArray];
-               
-               for ( int i = 0 ; i < nArray ; ++i )
-               {
-                       ret[i] = array[i];
-               }
-               
-               return ret;
-       }
-       
-       /**
-        * Convert <code>array</code> to {@link Character[]}
-        
-        * @param array array to convert
-        
-        * @return converted array
-        */
-       public static Character[] convertToWrapper( final char[] array )
-       {
-               final int nArray = size( array );
-               final Character[] ret = new Character[nArray];
-               
-               for ( int i = 0 ; i < nArray ; ++i )
-               {
-                       ret[i] = array[i];
-               }
-               
-               return ret;
-       }
-       
-       
-       /**
-        * Convert <code>array</code> to {@link Short[]}
-        
-        * @param array array to convert
-        
-        * @return converted array
-        */
-       public static Short[] convertToWrapper( final short[] array )
-       {
-               final int nArray = size( array );
-               final Short[] ret = new Short[nArray];
-               
-               for ( int i = 0 ; i < nArray ; ++i )
-               {
-                       ret[i] = array[i];
-               }
-               
-               return ret;
-       }
-       
-       /**
-        * Convert <code>array</code> to {@link Integer[]}
-        
-        * @param array array to convert
-        
-        * @return converted array
-        */
-       public static Integer[] convertToWrapper( final int[] array )
-       {
-               final int nArray = size( array );
-               final Integer[] ret = new Integer[nArray];
-               
-               for ( int i = 0 ; i < nArray ; ++i )
-               {
-                       ret[i] = array[i];
-               }
-               
-               return ret;
-       }
+    /**
+     * Convert <code>array</code> to {@link Byte[]}
+     * 
+     * @param array array to convert
+     * 
+     * @return converted array
+     */
+    public static Byte[] convertToWrapper( final byte[] array )
+    {
+        final int nArray = size( array );
+        final Byte[] ret = new Byte[nArray];
+        
+        for ( int i = 0 ; i < nArray ; ++i )
+        {
+            ret[i] = array[i];
+        }
+        
+        return ret;
+    }
+    
+    /**
+     * Convert <code>array</code> to {@link Character[]}
+     * 
+     * @param array array to convert
+     * 
+     * @return converted array
+     */
+    public static Character[] convertToWrapper( final char[] array )
+    {
+        final int nArray = size( array );
+        final Character[] ret = new Character[nArray];
+        
+        for ( int i = 0 ; i < nArray ; ++i )
+        {
+            ret[i] = array[i];
+        }
+        
+        return ret;
+    }
+    
+    
+    /**
+     * Convert <code>array</code> to {@link Short[]}
+     * 
+     * @param array array to convert
+     * 
+     * @return converted array
+     */
+    public static Short[] convertToWrapper( final short[] array )
+    {
+        final int nArray = size( array );
+        final Short[] ret = new Short[nArray];
+        
+        for ( int i = 0 ; i < nArray ; ++i )
+        {
+            ret[i] = array[i];
+        }
+        
+        return ret;
+    }
+    
+    /**
+     * Convert <code>array</code> to {@link Integer[]}
+     * 
+     * @param array array to convert
+     * 
+     * @return converted array
+     */
+    public static Integer[] convertToWrapper( final int[] array )
+    {
+        final int nArray = size( array );
+        final Integer[] ret = new Integer[nArray];
+        
+        for ( int i = 0 ; i < nArray ; ++i )
+        {
+            ret[i] = array[i];
+        }
+        
+        return ret;
+    }
 
-       /**
-        * Convert <code>array</code> to {@link Long[]}
-        
-        * @param array array to convert
-        
-        * @return converted array
-        */
-       public static Long[] convertToWrapper( final long[] array )
-       {
-               final int nArray = size( array );
-               final Long[] ret = new Long[nArray];
-               
-               for ( int i = 0 ; i < nArray ; ++i )
-               {
-                       ret[i] = array[i];
-               }
-               
-               return ret;
-       }
+    /**
+     * Convert <code>array</code> to {@link Long[]}
+     * 
+     * @param array array to convert
+     * 
+     * @return converted array
+     */
+    public static Long[] convertToWrapper( final long[] array )
+    {
+        final int nArray = size( array );
+        final Long[] ret = new Long[nArray];
+        
+        for ( int i = 0 ; i < nArray ; ++i )
+        {
+            ret[i] = array[i];
+        }
+        
+        return ret;
+    }
 
-       /**
-        * Convert <code>array</code> to {@link Float[]}
-        
-        * @param array array to convert
-        
-        * @return converted array
-        */
-       public static Float[] convertToWrapper( final float[] array )
-       {
-               final int nArray = size( array );
-               final Float[] ret = new Float[nArray];
-               
-               for ( int i = 0 ; i < nArray ; ++i )
-               {
-                       ret[i] = array[i];
-               }
-               
-               return ret;
-       }
+    /**
+     * Convert <code>array</code> to {@link Float[]}
+     * 
+     * @param array array to convert
+     * 
+     * @return converted array
+     */
+    public static Float[] convertToWrapper( final float[] array )
+    {
+        final int nArray = size( array );
+        final Float[] ret = new Float[nArray];
+        
+        for ( int i = 0 ; i < nArray ; ++i )
+        {
+            ret[i] = array[i];
+        }
+        
+        return ret;
+    }
 
-       /**
-        * Convert <code>array</code> to {@link Double[]}
-        
-        * @param array array to convert
-        
-        * @return converted array
-        */
-       public static Double[] convertToWrapper( final double[] array )
-       {
-               final int nArray = size( array );
-               final Double[] ret = new Double[nArray];
-               
-               for ( int i = 0 ; i < nArray ; ++i )
-               {
-                       ret[i] = array[i];
-               }
-               
-               return ret;
-       }
+    /**
+     * Convert <code>array</code> to {@link Double[]}
+     * 
+     * @param array array to convert
+     * 
+     * @return converted array
+     */
+    public static Double[] convertToWrapper( final double[] array )
+    {
+        final int nArray = size( array );
+        final Double[] ret = new Double[nArray];
+        
+        for ( int i = 0 ; i < nArray ; ++i )
+        {
+            ret[i] = array[i];
+        }
+        
+        return ret;
+    }
 
-       @SuppressWarnings("unchecked")
+    @SuppressWarnings("unchecked")
     public static <T> T[] safe( T[] unsafe )
-       {
-           return (T[]) ObjectUtil.nvl( unsafe, EMPTY_OBJECT_ARRAY );
-       }
+    {
+        return (T[]) ObjectUtil.nvl( unsafe, EMPTY_OBJECT_ARRAY );
+    }
+
+    /**
+     * <p>Produces a new array containing the elements between
+     * the start and end indices.
+     * 
+     * @return a new array containing the elements between
+     *      the start and end indices.
+     */
+    public static Object[] subarray( Object[] array, int startIndexInclusive, int endIndexExclusive )
+    {
+        if (array == null)
+        {
+            return null;
+        }
+        if (startIndexInclusive < 0)
+        {
+            startIndexInclusive = 0;
+        }
+        if (endIndexExclusive > array.length)
+        {
+            endIndexExclusive = array.length;
+        }
+        int newSize = endIndexExclusive - startIndexInclusive;
+        Class type = array.getClass().getComponentType();
+        if (newSize <= 0)
+        {
+            return (Object[]) Array.newInstance(type, 0);
+        }
+        Object[] subarray = (Object[]) Array.newInstance(type, newSize);
+        System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
+        return subarray;
+    }
 }