001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     * 
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     * 
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.commons.lang;
018    
019    import java.lang.reflect.Array;
020    import java.util.HashMap;
021    import java.util.Map;
022    
023    import org.apache.commons.lang.builder.EqualsBuilder;
024    import org.apache.commons.lang.builder.HashCodeBuilder;
025    import org.apache.commons.lang.builder.ToStringBuilder;
026    import org.apache.commons.lang.builder.ToStringStyle;
027    
028    /**
029     * <p>Operations on arrays, primitive arrays (like <code>int[]</code>) and
030     * primitive wrapper arrays (like <code>Integer[]</code>).</p>
031     * 
032     * <p>This class tries to handle <code>null</code> input gracefully.
033     * An exception will not be thrown for a <code>null</code>
034     * array input. However, an Object array that contains a <code>null</code>
035     * element may throw an exception. Each method documents its behaviour.</p>
036     *
037     * @author Stephen Colebourne
038     * @author Moritz Petersen
039     * @author <a href="mailto:fredrik@westermarck.com">Fredrik Westermarck</a>
040     * @author Nikolay Metchev
041     * @author Matthew Hawthorne
042     * @author Tim O'Brien
043     * @author Pete Gieser
044     * @author Gary Gregory
045     * @author <a href="mailto:equinus100@hotmail.com">Ashwin S</a>
046     * @author Maarten Coene
047     * @since 2.0
048     * @version $Id: ArrayUtils.java 632503 2008-03-01 00:21:52Z ggregory $
049     */
050    public class ArrayUtils {
051    
052        /**
053         * An empty immutable <code>Object</code> array.
054         */
055        public static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
056        /**
057         * An empty immutable <code>Class</code> array.
058         */
059        public static final Class[] EMPTY_CLASS_ARRAY = new Class[0];
060        /**
061         * An empty immutable <code>String</code> array.
062         */
063        public static final String[] EMPTY_STRING_ARRAY = new String[0];
064        /**
065         * An empty immutable <code>long</code> array.
066         */
067        public static final long[] EMPTY_LONG_ARRAY = new long[0];
068        /**
069         * An empty immutable <code>Long</code> array.
070         */
071        public static final Long[] EMPTY_LONG_OBJECT_ARRAY = new Long[0];
072        /**
073         * An empty immutable <code>int</code> array.
074         */
075        public static final int[] EMPTY_INT_ARRAY = new int[0];
076        /**
077         * An empty immutable <code>Integer</code> array.
078         */
079        public static final Integer[] EMPTY_INTEGER_OBJECT_ARRAY = new Integer[0];
080        /**
081         * An empty immutable <code>short</code> array.
082         */
083        public static final short[] EMPTY_SHORT_ARRAY = new short[0];
084        /**
085         * An empty immutable <code>Short</code> array.
086         */
087        public static final Short[] EMPTY_SHORT_OBJECT_ARRAY = new Short[0];
088        /**
089         * An empty immutable <code>byte</code> array.
090         */
091        public static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
092        /**
093         * An empty immutable <code>Byte</code> array.
094         */
095        public static final Byte[] EMPTY_BYTE_OBJECT_ARRAY = new Byte[0];
096        /**
097         * An empty immutable <code>double</code> array.
098         */
099        public static final double[] EMPTY_DOUBLE_ARRAY = new double[0];
100        /**
101         * An empty immutable <code>Double</code> array.
102         */
103        public static final Double[] EMPTY_DOUBLE_OBJECT_ARRAY = new Double[0];
104        /**
105         * An empty immutable <code>float</code> array.
106         */
107        public static final float[] EMPTY_FLOAT_ARRAY = new float[0];
108        /**
109         * An empty immutable <code>Float</code> array.
110         */
111        public static final Float[] EMPTY_FLOAT_OBJECT_ARRAY = new Float[0];
112        /**
113         * An empty immutable <code>boolean</code> array.
114         */
115        public static final boolean[] EMPTY_BOOLEAN_ARRAY = new boolean[0];
116        /**
117         * An empty immutable <code>Boolean</code> array.
118         */
119        public static final Boolean[] EMPTY_BOOLEAN_OBJECT_ARRAY = new Boolean[0];
120        /**
121         * An empty immutable <code>char</code> array.
122         */
123        public static final char[] EMPTY_CHAR_ARRAY = new char[0];
124        /**
125         * An empty immutable <code>Character</code> array.
126         */
127        public static final Character[] EMPTY_CHARACTER_OBJECT_ARRAY = new Character[0];
128    
129        /**
130         * The index value when an element is not found in a list or array: <code>-1</code>.
131         * This value is returned by methods in this class and can also be used in comparisons with values returned by
132         * various method from {@link java.util.List}.
133         */
134        public static final int INDEX_NOT_FOUND = -1;
135    
136        /**
137         * <p>ArrayUtils instances should NOT be constructed in standard programming.
138         * Instead, the class should be used as <code>ArrayUtils.clone(new int[] {2})</code>.</p>
139         *
140         * <p>This constructor is public to permit tools that require a JavaBean instance
141         * to operate.</p>
142         */
143        public ArrayUtils() {
144          super();
145        }
146        
147        // Basic methods handling multi-dimensional arrays
148        //-----------------------------------------------------------------------
149        /**
150         * <p>Outputs an array as a String, treating <code>null</code> as an empty array.</p>
151         *
152         * <p>Multi-dimensional arrays are handled correctly, including
153         * multi-dimensional primitive arrays.</p>
154         *
155         * <p>The format is that of Java source code, for example <code>{a,b}</code>.</p>
156         * 
157         * @param array  the array to get a toString for, may be <code>null</code>
158         * @return a String representation of the array, '{}' if null array input
159         */
160        public static String toString(Object array) {
161            return toString(array, "{}");
162        }
163    
164        /**
165         * <p>Outputs an array as a String handling <code>null</code>s.</p>
166         *
167         * <p>Multi-dimensional arrays are handled correctly, including
168         * multi-dimensional primitive arrays.</p>
169         *
170         * <p>The format is that of Java source code, for example <code>{a,b}</code>.</p>
171         * 
172         * @param array  the array to get a toString for, may be <code>null</code>
173         * @param stringIfNull  the String to return if the array is <code>null</code>
174         * @return a String representation of the array
175         */    
176        public static String toString(Object array, String stringIfNull) {
177            if (array == null) {
178                return stringIfNull;
179            }
180            return new ToStringBuilder(array, ToStringStyle.SIMPLE_STYLE).append(array).toString();
181        }
182    
183        /**
184         * <p>Get a hashCode for an array handling multi-dimensional arrays correctly.</p>
185         * 
186         * <p>Multi-dimensional primitive arrays are also handled correctly by this method.</p>
187         * 
188         * @param array  the array to get a hashCode for, may be <code>null</code>
189         * @return a hashCode for the array, zero if null array input
190         */
191        public static int hashCode(Object array) {
192            return new HashCodeBuilder().append(array).toHashCode();
193        }
194    
195        /**
196         * <p>Compares two arrays, using equals(), handling multi-dimensional arrays
197         * correctly.</p>
198         * 
199         * <p>Multi-dimensional primitive arrays are also handled correctly by this method.</p>
200         * 
201         * @param array1  the left hand array to compare, may be <code>null</code>
202         * @param array2  the right hand array to compare, may be <code>null</code>
203         * @return <code>true</code> if the arrays are equal
204         */
205        public static boolean isEquals(Object array1, Object array2) {
206            return new EqualsBuilder().append(array1, array2).isEquals();
207        }
208    
209        // To map
210        //-----------------------------------------------------------------------
211        /**
212         * <p>Converts the given array into a {@link java.util.Map}. Each element of the array
213         * must be either a {@link java.util.Map.Entry} or an Array, containing at least two
214         * elements, where the first element is used as key and the second as
215         * value.</p>
216         *
217         * <p>This method can be used to initialize:</p>
218         * <pre>
219         * // Create a Map mapping colors.
220         * Map colorMap = MapUtils.toMap(new String[][] {{
221         *     {"RED", "#FF0000"},
222         *     {"GREEN", "#00FF00"},
223         *     {"BLUE", "#0000FF"}});
224         * </pre>
225         * 
226         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
227         *
228         * @param array  an array whose elements are either a {@link java.util.Map.Entry} or
229         *  an Array containing at least two elements, may be <code>null</code>
230         * @return a <code>Map</code> that was created from the array
231         * @throws IllegalArgumentException  if one element of this Array is
232         *  itself an Array containing less then two elements
233         * @throws IllegalArgumentException  if the array contains elements other
234         *  than {@link java.util.Map.Entry} and an Array
235         */
236        public static Map toMap(Object[] array) {
237            if (array == null) {
238                return null;
239            }
240            final Map map = new HashMap((int) (array.length * 1.5));
241            for (int i = 0; i < array.length; i++) {
242                Object object = array[i];
243                if (object instanceof Map.Entry) {
244                    Map.Entry entry = (Map.Entry) object;
245                    map.put(entry.getKey(), entry.getValue());
246                } else if (object instanceof Object[]) {
247                    Object[] entry = (Object[]) object;
248                    if (entry.length < 2) {
249                        throw new IllegalArgumentException("Array element " + i + ", '"
250                            + object
251                            + "', has a length less than 2");
252                    }
253                    map.put(entry[0], entry[1]);
254                } else {
255                    throw new IllegalArgumentException("Array element " + i + ", '"
256                            + object
257                            + "', is neither of type Map.Entry nor an Array");
258                }
259            }
260            return map;
261        }
262    
263        // Clone
264        //-----------------------------------------------------------------------
265        /**
266         * <p>Shallow clones an array returning a typecast result and handling
267         * <code>null</code>.</p>
268         *
269         * <p>The objects in the array are not cloned, thus there is no special
270         * handling for multi-dimensional arrays.</p>
271         * 
272         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
273         * 
274         * @param array  the array to shallow clone, may be <code>null</code>
275         * @return the cloned array, <code>null</code> if <code>null</code> input
276         */
277        public static Object[] clone(Object[] array) {
278            if (array == null) {
279                return null;
280            }
281            return (Object[]) array.clone();
282        }
283    
284        /**
285         * <p>Clones an array returning a typecast result and handling
286         * <code>null</code>.</p>
287         *
288         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
289         * 
290         * @param array  the array to clone, may be <code>null</code>
291         * @return the cloned array, <code>null</code> if <code>null</code> input
292         */
293        public static long[] clone(long[] array) {
294            if (array == null) {
295                return null;
296            }
297            return (long[]) array.clone();
298        }
299    
300        /**
301         * <p>Clones an array returning a typecast result and handling
302         * <code>null</code>.</p>
303         *
304         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
305         * 
306         * @param array  the array to clone, may be <code>null</code>
307         * @return the cloned array, <code>null</code> if <code>null</code> input
308         */
309        public static int[] clone(int[] array) {
310            if (array == null) {
311                return null;
312            }
313            return (int[]) array.clone();
314        }
315    
316        /**
317         * <p>Clones an array returning a typecast result and handling
318         * <code>null</code>.</p>
319         *
320         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
321         * 
322         * @param array  the array to clone, may be <code>null</code>
323         * @return the cloned array, <code>null</code> if <code>null</code> input
324         */
325        public static short[] clone(short[] array) {
326            if (array == null) {
327                return null;
328            }
329            return (short[]) array.clone();
330        }
331    
332        /**
333         * <p>Clones an array returning a typecast result and handling
334         * <code>null</code>.</p>
335         *
336         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
337         * 
338         * @param array  the array to clone, may be <code>null</code>
339         * @return the cloned array, <code>null</code> if <code>null</code> input
340         */
341        public static char[] clone(char[] array) {
342            if (array == null) {
343                return null;
344            }
345            return (char[]) array.clone();
346        }
347    
348        /**
349         * <p>Clones an array returning a typecast result and handling
350         * <code>null</code>.</p>
351         *
352         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
353         * 
354         * @param array  the array to clone, may be <code>null</code>
355         * @return the cloned array, <code>null</code> if <code>null</code> input
356         */
357        public static byte[] clone(byte[] array) {
358            if (array == null) {
359                return null;
360            }
361            return (byte[]) array.clone();
362        }
363    
364        /**
365         * <p>Clones an array returning a typecast result and handling
366         * <code>null</code>.</p>
367         *
368         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
369         * 
370         * @param array  the array to clone, may be <code>null</code>
371         * @return the cloned array, <code>null</code> if <code>null</code> input
372         */
373        public static double[] clone(double[] array) {
374            if (array == null) {
375                return null;
376            }
377            return (double[]) array.clone();
378        }
379    
380        /**
381         * <p>Clones an array returning a typecast result and handling
382         * <code>null</code>.</p>
383         *
384         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
385         * 
386         * @param array  the array to clone, may be <code>null</code>
387         * @return the cloned array, <code>null</code> if <code>null</code> input
388         */
389        public static float[] clone(float[] array) {
390            if (array == null) {
391                return null;
392            }
393            return (float[]) array.clone();
394        }
395    
396        /**
397         * <p>Clones an array returning a typecast result and handling
398         * <code>null</code>.</p>
399         *
400         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
401         * 
402         * @param array  the array to clone, may be <code>null</code>
403         * @return the cloned array, <code>null</code> if <code>null</code> input
404         */
405        public static boolean[] clone(boolean[] array) {
406            if (array == null) {
407                return null;
408            }
409            return (boolean[]) array.clone();
410        }
411    
412        // Subarrays
413        //-----------------------------------------------------------------------
414        /**
415         * <p>Produces a new array containing the elements between
416         * the start and end indices.</p>
417         *
418         * <p>The start index is inclusive, the end index exclusive.
419         * Null array input produces null output.</p>
420         *
421         * <p>The component type of the subarray is always the same as
422         * that of the input array. Thus, if the input is an array of type
423         * <code>Date</code>, the following usage is envisaged:</p>
424         *
425         * <pre>
426         * Date[] someDates = (Date[])ArrayUtils.subarray(allDates, 2, 5);
427         * </pre>
428         *
429         * @param array  the array
430         * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
431         *      is promoted to 0, overvalue (&gt;array.length) results
432         *      in an empty array.
433         * @param endIndexExclusive  elements up to endIndex-1 are present in the
434         *      returned subarray. Undervalue (&lt; startIndex) produces
435         *      empty array, overvalue (&gt;array.length) is demoted to
436         *      array length.
437         * @return a new array containing the elements between
438         *      the start and end indices.
439         * @since 2.1
440         */
441        public static Object[] subarray(Object[] array, int startIndexInclusive, int endIndexExclusive) {
442            if (array == null) {
443                return null;
444            }
445            if (startIndexInclusive < 0) {
446                startIndexInclusive = 0;
447            }
448            if (endIndexExclusive > array.length) {
449                endIndexExclusive = array.length;
450            }
451            int newSize = endIndexExclusive - startIndexInclusive;
452            Class type = array.getClass().getComponentType();
453            if (newSize <= 0) {
454                return (Object[]) Array.newInstance(type, 0);
455            }
456            Object[] subarray = (Object[]) Array.newInstance(type, newSize);
457            System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
458            return subarray;
459        }
460    
461        /**
462         * <p>Produces a new <code>long</code> array containing the elements
463         * between the start and end indices.</p>
464         *
465         * <p>The start index is inclusive, the end index exclusive.
466         * Null array input produces null output.</p>
467         *
468         * @param array  the array
469         * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
470         *      is promoted to 0, overvalue (&gt;array.length) results
471         *      in an empty array.
472         * @param endIndexExclusive  elements up to endIndex-1 are present in the
473         *      returned subarray. Undervalue (&lt; startIndex) produces
474         *      empty array, overvalue (&gt;array.length) is demoted to
475         *      array length.
476         * @return a new array containing the elements between
477         *      the start and end indices.
478         * @since 2.1
479         */
480        public static long[] subarray(long[] array, int startIndexInclusive, int endIndexExclusive) {
481            if (array == null) {
482                return null;
483            }
484            if (startIndexInclusive < 0) {
485                startIndexInclusive = 0;
486            }
487            if (endIndexExclusive > array.length) {
488                endIndexExclusive = array.length;
489            }
490            int newSize = endIndexExclusive - startIndexInclusive;
491            if (newSize <= 0) {
492                return EMPTY_LONG_ARRAY;
493            }
494    
495            long[] subarray = new long[newSize];
496            System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
497            return subarray;
498        }
499    
500        /**
501         * <p>Produces a new <code>int</code> array containing the elements
502         * between the start and end indices.</p>
503         *
504         * <p>The start index is inclusive, the end index exclusive.
505         * Null array input produces null output.</p>
506         *
507         * @param array  the array
508         * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
509         *      is promoted to 0, overvalue (&gt;array.length) results
510         *      in an empty array.
511         * @param endIndexExclusive  elements up to endIndex-1 are present in the
512         *      returned subarray. Undervalue (&lt; startIndex) produces
513         *      empty array, overvalue (&gt;array.length) is demoted to
514         *      array length.
515         * @return a new array containing the elements between
516         *      the start and end indices.
517         * @since 2.1
518         */
519        public static int[] subarray(int[] array, int startIndexInclusive, int endIndexExclusive) {
520            if (array == null) {
521                return null;
522            }
523            if (startIndexInclusive < 0) {
524                startIndexInclusive = 0;
525            }
526            if (endIndexExclusive > array.length) {
527                endIndexExclusive = array.length;
528            }
529            int newSize = endIndexExclusive - startIndexInclusive;
530            if (newSize <= 0) {
531                return EMPTY_INT_ARRAY;
532            }
533    
534            int[] subarray = new int[newSize];
535            System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
536            return subarray;
537        }
538    
539        /**
540         * <p>Produces a new <code>short</code> array containing the elements
541         * between the start and end indices.</p>
542         *
543         * <p>The start index is inclusive, the end index exclusive.
544         * Null array input produces null output.</p>
545         *
546         * @param array  the array
547         * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
548         *      is promoted to 0, overvalue (&gt;array.length) results
549         *      in an empty array.
550         * @param endIndexExclusive  elements up to endIndex-1 are present in the
551         *      returned subarray. Undervalue (&lt; startIndex) produces
552         *      empty array, overvalue (&gt;array.length) is demoted to
553         *      array length.
554         * @return a new array containing the elements between
555         *      the start and end indices.
556         * @since 2.1
557         */
558        public static short[] subarray(short[] array, int startIndexInclusive, int endIndexExclusive) {
559            if (array == null) {
560                return null;
561            }
562            if (startIndexInclusive < 0) {
563                startIndexInclusive = 0;
564            }
565            if (endIndexExclusive > array.length) {
566                endIndexExclusive = array.length;
567            }
568            int newSize = endIndexExclusive - startIndexInclusive;
569            if (newSize <= 0) {
570                return EMPTY_SHORT_ARRAY;
571            }
572    
573            short[] subarray = new short[newSize];
574            System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
575            return subarray;
576        }
577    
578        /**
579         * <p>Produces a new <code>char</code> array containing the elements
580         * between the start and end indices.</p>
581         *
582         * <p>The start index is inclusive, the end index exclusive.
583         * Null array input produces null output.</p>
584         *
585         * @param array  the array
586         * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
587         *      is promoted to 0, overvalue (&gt;array.length) results
588         *      in an empty array.
589         * @param endIndexExclusive  elements up to endIndex-1 are present in the
590         *      returned subarray. Undervalue (&lt; startIndex) produces
591         *      empty array, overvalue (&gt;array.length) is demoted to
592         *      array length.
593         * @return a new array containing the elements between
594         *      the start and end indices.
595         * @since 2.1
596         */
597        public static char[] subarray(char[] array, int startIndexInclusive, int endIndexExclusive) {
598            if (array == null) {
599                return null;
600            }
601            if (startIndexInclusive < 0) {
602                startIndexInclusive = 0;
603            }
604            if (endIndexExclusive > array.length) {
605                endIndexExclusive = array.length;
606            }
607            int newSize = endIndexExclusive - startIndexInclusive;
608            if (newSize <= 0) {
609                return EMPTY_CHAR_ARRAY;
610            }
611    
612            char[] subarray = new char[newSize];
613            System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
614            return subarray;
615        }
616    
617        /**
618         * <p>Produces a new <code>byte</code> array containing the elements
619         * between the start and end indices.</p>
620         *
621         * <p>The start index is inclusive, the end index exclusive.
622         * Null array input produces null output.</p>
623         *
624         * @param array  the array
625         * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
626         *      is promoted to 0, overvalue (&gt;array.length) results
627         *      in an empty array.
628         * @param endIndexExclusive  elements up to endIndex-1 are present in the
629         *      returned subarray. Undervalue (&lt; startIndex) produces
630         *      empty array, overvalue (&gt;array.length) is demoted to
631         *      array length.
632         * @return a new array containing the elements between
633         *      the start and end indices.
634         * @since 2.1
635         */
636        public static byte[] subarray(byte[] array, int startIndexInclusive, int endIndexExclusive) {
637            if (array == null) {
638                return null;
639            }
640            if (startIndexInclusive < 0) {
641                startIndexInclusive = 0;
642            }
643            if (endIndexExclusive > array.length) {
644                endIndexExclusive = array.length;
645            }
646            int newSize = endIndexExclusive - startIndexInclusive;
647            if (newSize <= 0) {
648                return EMPTY_BYTE_ARRAY;
649            }
650    
651            byte[] subarray = new byte[newSize];
652            System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
653            return subarray;
654        }
655    
656        /**
657         * <p>Produces a new <code>double</code> array containing the elements
658         * between the start and end indices.</p>
659         *
660         * <p>The start index is inclusive, the end index exclusive.
661         * Null array input produces null output.</p>
662         *
663         * @param array  the array
664         * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
665         *      is promoted to 0, overvalue (&gt;array.length) results
666         *      in an empty array.
667         * @param endIndexExclusive  elements up to endIndex-1 are present in the
668         *      returned subarray. Undervalue (&lt; startIndex) produces
669         *      empty array, overvalue (&gt;array.length) is demoted to
670         *      array length.
671         * @return a new array containing the elements between
672         *      the start and end indices.
673         * @since 2.1
674         */
675        public static double[] subarray(double[] array, int startIndexInclusive, int endIndexExclusive) {
676            if (array == null) {
677                return null;
678            }
679            if (startIndexInclusive < 0) {
680                startIndexInclusive = 0;
681            }
682            if (endIndexExclusive > array.length) {
683                endIndexExclusive = array.length;
684            }
685            int newSize = endIndexExclusive - startIndexInclusive;
686            if (newSize <= 0) {
687                return EMPTY_DOUBLE_ARRAY;
688            }
689    
690            double[] subarray = new double[newSize];
691            System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
692            return subarray;
693        }
694    
695        /**
696         * <p>Produces a new <code>float</code> array containing the elements
697         * between the start and end indices.</p>
698         *
699         * <p>The start index is inclusive, the end index exclusive.
700         * Null array input produces null output.</p>
701         *
702         * @param array  the array
703         * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
704         *      is promoted to 0, overvalue (&gt;array.length) results
705         *      in an empty array.
706         * @param endIndexExclusive  elements up to endIndex-1 are present in the
707         *      returned subarray. Undervalue (&lt; startIndex) produces
708         *      empty array, overvalue (&gt;array.length) is demoted to
709         *      array length.
710         * @return a new array containing the elements between
711         *      the start and end indices.
712         * @since 2.1
713         */
714        public static float[] subarray(float[] array, int startIndexInclusive, int endIndexExclusive) {
715            if (array == null) {
716                return null;
717            }
718            if (startIndexInclusive < 0) {
719                startIndexInclusive = 0;
720            }
721            if (endIndexExclusive > array.length) {
722                endIndexExclusive = array.length;
723            }
724            int newSize = endIndexExclusive - startIndexInclusive;
725            if (newSize <= 0) {
726                return EMPTY_FLOAT_ARRAY;
727            }
728    
729            float[] subarray = new float[newSize];
730            System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
731            return subarray;
732        }
733    
734        /**
735         * <p>Produces a new <code>boolean</code> array containing the elements
736         * between the start and end indices.</p>
737         *
738         * <p>The start index is inclusive, the end index exclusive.
739         * Null array input produces null output.</p>
740         *
741         * @param array  the array
742         * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
743         *      is promoted to 0, overvalue (&gt;array.length) results
744         *      in an empty array.
745         * @param endIndexExclusive  elements up to endIndex-1 are present in the
746         *      returned subarray. Undervalue (&lt; startIndex) produces
747         *      empty array, overvalue (&gt;array.length) is demoted to
748         *      array length.
749         * @return a new array containing the elements between
750         *      the start and end indices.
751         * @since 2.1
752         */
753        public static boolean[] subarray(boolean[] array, int startIndexInclusive, int endIndexExclusive) {
754            if (array == null) {
755                return null;
756            }
757            if (startIndexInclusive < 0) {
758                startIndexInclusive = 0;
759            }
760            if (endIndexExclusive > array.length) {
761                endIndexExclusive = array.length;
762            }
763            int newSize = endIndexExclusive - startIndexInclusive;
764            if (newSize <= 0) {
765                return EMPTY_BOOLEAN_ARRAY;
766            }
767    
768            boolean[] subarray = new boolean[newSize];
769            System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
770            return subarray;
771        }
772    
773        // Is same length
774        //-----------------------------------------------------------------------
775        /**
776         * <p>Checks whether two arrays are the same length, treating
777         * <code>null</code> arrays as length <code>0</code>.
778         *
779         * <p>Any multi-dimensional aspects of the arrays are ignored.</p>
780         * 
781         * @param array1 the first array, may be <code>null</code>
782         * @param array2 the second array, may be <code>null</code>
783         * @return <code>true</code> if length of arrays matches, treating
784         *  <code>null</code> as an empty array
785         */    
786        public static boolean isSameLength(Object[] array1, Object[] array2) {
787            if ((array1 == null && array2 != null && array2.length > 0) ||
788                (array2 == null && array1 != null && array1.length > 0) ||
789                (array1 != null && array2 != null && array1.length != array2.length)) {
790                    return false;
791            }
792            return true;
793        }
794    
795        /**
796         * <p>Checks whether two arrays are the same length, treating
797         * <code>null</code> arrays as length <code>0</code>.</p>
798         * 
799         * @param array1 the first array, may be <code>null</code>
800         * @param array2 the second array, may be <code>null</code>
801         * @return <code>true</code> if length of arrays matches, treating
802         *  <code>null</code> as an empty array
803         */
804        public static boolean isSameLength(long[] array1, long[] array2) {
805            if ((array1 == null && array2 != null && array2.length > 0) ||
806                (array2 == null && array1 != null && array1.length > 0) ||
807                (array1 != null && array2 != null && array1.length != array2.length)) {
808                    return false;
809            }
810            return true;
811        }
812    
813        /**
814         * <p>Checks whether two arrays are the same length, treating
815         * <code>null</code> arrays as length <code>0</code>.</p>
816         * 
817         * @param array1 the first array, may be <code>null</code>
818         * @param array2 the second array, may be <code>null</code>
819         * @return <code>true</code> if length of arrays matches, treating
820         *  <code>null</code> as an empty array
821         */
822        public static boolean isSameLength(int[] array1, int[] array2) {
823            if ((array1 == null && array2 != null && array2.length > 0) ||
824                (array2 == null && array1 != null && array1.length > 0) ||
825                (array1 != null && array2 != null && array1.length != array2.length)) {
826                    return false;
827            }
828            return true;
829        }
830    
831        /**
832         * <p>Checks whether two arrays are the same length, treating
833         * <code>null</code> arrays as length <code>0</code>.</p>
834         * 
835         * @param array1 the first array, may be <code>null</code>
836         * @param array2 the second array, may be <code>null</code>
837         * @return <code>true</code> if length of arrays matches, treating
838         *  <code>null</code> as an empty array
839         */
840        public static boolean isSameLength(short[] array1, short[] array2) {
841            if ((array1 == null && array2 != null && array2.length > 0) ||
842                (array2 == null && array1 != null && array1.length > 0) ||
843                (array1 != null && array2 != null && array1.length != array2.length)) {
844                    return false;
845            }
846            return true;
847        }
848    
849        /**
850         * <p>Checks whether two arrays are the same length, treating
851         * <code>null</code> arrays as length <code>0</code>.</p>
852         * 
853         * @param array1 the first array, may be <code>null</code>
854         * @param array2 the second array, may be <code>null</code>
855         * @return <code>true</code> if length of arrays matches, treating
856         *  <code>null</code> as an empty array
857         */
858        public static boolean isSameLength(char[] array1, char[] array2) {
859            if ((array1 == null && array2 != null && array2.length > 0) ||
860                (array2 == null && array1 != null && array1.length > 0) ||
861                (array1 != null && array2 != null && array1.length != array2.length)) {
862                    return false;
863            }
864            return true;
865        }
866    
867        /**
868         * <p>Checks whether two arrays are the same length, treating
869         * <code>null</code> arrays as length <code>0</code>.</p>
870         * 
871         * @param array1 the first array, may be <code>null</code>
872         * @param array2 the second array, may be <code>null</code>
873         * @return <code>true</code> if length of arrays matches, treating
874         *  <code>null</code> as an empty array
875         */
876        public static boolean isSameLength(byte[] array1, byte[] array2) {
877            if ((array1 == null && array2 != null && array2.length > 0) ||
878                (array2 == null && array1 != null && array1.length > 0) ||
879                (array1 != null && array2 != null && array1.length != array2.length)) {
880                    return false;
881            }
882            return true;
883        }
884    
885        /**
886         * <p>Checks whether two arrays are the same length, treating
887         * <code>null</code> arrays as length <code>0</code>.</p>
888         * 
889         * @param array1 the first array, may be <code>null</code>
890         * @param array2 the second array, may be <code>null</code>
891         * @return <code>true</code> if length of arrays matches, treating
892         *  <code>null</code> as an empty array
893         */
894        public static boolean isSameLength(double[] array1, double[] array2) {
895            if ((array1 == null && array2 != null && array2.length > 0) ||
896                (array2 == null && array1 != null && array1.length > 0) ||
897                (array1 != null && array2 != null && array1.length != array2.length)) {
898                    return false;
899            }
900            return true;
901        }
902    
903        /**
904         * <p>Checks whether two arrays are the same length, treating
905         * <code>null</code> arrays as length <code>0</code>.</p>
906         * 
907         * @param array1 the first array, may be <code>null</code>
908         * @param array2 the second array, may be <code>null</code>
909         * @return <code>true</code> if length of arrays matches, treating
910         *  <code>null</code> as an empty array
911         */
912        public static boolean isSameLength(float[] array1, float[] array2) {
913            if ((array1 == null && array2 != null && array2.length > 0) ||
914                (array2 == null && array1 != null && array1.length > 0) ||
915                (array1 != null && array2 != null && array1.length != array2.length)) {
916                    return false;
917            }
918            return true;
919        }
920    
921        /**
922         * <p>Checks whether two arrays are the same length, treating
923         * <code>null</code> arrays as length <code>0</code>.</p>
924         * 
925         * @param array1 the first array, may be <code>null</code>
926         * @param array2 the second array, may be <code>null</code>
927         * @return <code>true</code> if length of arrays matches, treating
928         *  <code>null</code> as an empty array
929         */
930        public static boolean isSameLength(boolean[] array1, boolean[] array2) {
931            if ((array1 == null && array2 != null && array2.length > 0) ||
932                (array2 == null && array1 != null && array1.length > 0) ||
933                (array1 != null && array2 != null && array1.length != array2.length)) {
934                    return false;
935            }
936            return true;
937        }
938    
939        //-----------------------------------------------------------------------
940        /**
941         * <p>Returns the length of the specified array.
942         * This method can deal with <code>Object</code> arrays and with primitive arrays.</p>
943         *
944         * <p>If the input array is <code>null</code>, <code>0</code> is returned.</p>
945         *
946         * <pre>
947         * ArrayUtils.getLength(null)            = 0
948         * ArrayUtils.getLength([])              = 0
949         * ArrayUtils.getLength([null])          = 1
950         * ArrayUtils.getLength([true, false])   = 2
951         * ArrayUtils.getLength([1, 2, 3])       = 3
952         * ArrayUtils.getLength(["a", "b", "c"]) = 3
953         * </pre>
954         *
955         * @param array  the array to retrieve the length from, may be null
956         * @return The length of the array, or <code>0</code> if the array is <code>null</code>
957         * @throws IllegalArgumentException if the object arguement is not an array.
958         * @since 2.1
959         */
960        public static int getLength(Object array) {
961            if (array == null) {
962                return 0;
963            }
964            return Array.getLength(array);
965        }
966    
967        /**
968         * <p>Checks whether two arrays are the same type taking into account
969         * multi-dimensional arrays.</p>
970         * 
971         * @param array1 the first array, must not be <code>null</code>
972         * @param array2 the second array, must not be <code>null</code>
973         * @return <code>true</code> if type of arrays matches
974         * @throws IllegalArgumentException if either array is <code>null</code>
975         */    
976        public static boolean isSameType(Object array1, Object array2) {
977            if (array1 == null || array2 == null) {
978                throw new IllegalArgumentException("The Array must not be null");
979            }
980            return array1.getClass().getName().equals(array2.getClass().getName());
981        }
982    
983        // Reverse
984        //-----------------------------------------------------------------------
985        /** 
986         * <p>Reverses the order of the given array.</p>
987         *
988         * <p>There is no special handling for multi-dimensional arrays.</p>
989         *
990         * <p>This method does nothing for a <code>null</code> input array.</p>
991         * 
992         * @param array  the array to reverse, may be <code>null</code>
993         */
994        public static void reverse(Object[] array) {
995            if (array == null) {
996                return;
997            }
998            int i = 0;
999            int j = array.length - 1;
1000            Object tmp;
1001            while (j > i) {
1002                tmp = array[j];
1003                array[j] = array[i];
1004                array[i] = tmp;
1005                j--;
1006                i++;
1007            }
1008        }
1009    
1010        /**
1011         * <p>Reverses the order of the given array.</p>
1012         * 
1013         * <p>This method does nothing for a <code>null</code> input array.</p>
1014         * 
1015         * @param array  the array to reverse, may be <code>null</code>
1016         */
1017        public static void reverse(long[] array) {
1018            if (array == null) {
1019                return;
1020            }
1021            int i = 0;
1022            int j = array.length - 1;
1023            long tmp;
1024            while (j > i) {
1025                tmp = array[j];
1026                array[j] = array[i];
1027                array[i] = tmp;
1028                j--;
1029                i++;
1030            }
1031        }
1032    
1033        /**
1034         * <p>Reverses the order of the given array.</p>
1035         * 
1036         * <p>This method does nothing for a <code>null</code> input array.</p>
1037         * 
1038         * @param array  the array to reverse, may be <code>null</code>
1039         */
1040        public static void reverse(int[] array) {
1041            if (array == null) {
1042                return;
1043            }
1044            int i = 0;
1045            int j = array.length - 1;
1046            int tmp;
1047            while (j > i) {
1048                tmp = array[j];
1049                array[j] = array[i];
1050                array[i] = tmp;
1051                j--;
1052                i++;
1053            }
1054        }
1055    
1056        /**
1057         * <p>Reverses the order of the given array.</p>
1058         * 
1059         * <p>This method does nothing for a <code>null</code> input array.</p>
1060         * 
1061         * @param array  the array to reverse, may be <code>null</code>
1062         */
1063        public static void reverse(short[] array) {
1064            if (array == null) {
1065                return;
1066            }
1067            int i = 0;
1068            int j = array.length - 1;
1069            short tmp;
1070            while (j > i) {
1071                tmp = array[j];
1072                array[j] = array[i];
1073                array[i] = tmp;
1074                j--;
1075                i++;
1076            }
1077        }
1078    
1079        /**
1080         * <p>Reverses the order of the given array.</p>
1081         * 
1082         * <p>This method does nothing for a <code>null</code> input array.</p>
1083         * 
1084         * @param array  the array to reverse, may be <code>null</code>
1085         */
1086        public static void reverse(char[] array) {
1087            if (array == null) {
1088                return;
1089            }
1090            int i = 0;
1091            int j = array.length - 1;
1092            char tmp;
1093            while (j > i) {
1094                tmp = array[j];
1095                array[j] = array[i];
1096                array[i] = tmp;
1097                j--;
1098                i++;
1099            }
1100        }
1101    
1102        /**
1103         * <p>Reverses the order of the given array.</p>
1104         * 
1105         * <p>This method does nothing for a <code>null</code> input array.</p>
1106         * 
1107         * @param array  the array to reverse, may be <code>null</code>
1108         */
1109        public static void reverse(byte[] array) {
1110            if (array == null) {
1111                return;
1112            }
1113            int i = 0;
1114            int j = array.length - 1;
1115            byte tmp;
1116            while (j > i) {
1117                tmp = array[j];
1118                array[j] = array[i];
1119                array[i] = tmp;
1120                j--;
1121                i++;
1122            }
1123        }
1124    
1125        /**
1126         * <p>Reverses the order of the given array.</p>
1127         * 
1128         * <p>This method does nothing for a <code>null</code> input array.</p>
1129         * 
1130         * @param array  the array to reverse, may be <code>null</code>
1131         */
1132        public static void reverse(double[] array) {
1133            if (array == null) {
1134                return;
1135            }
1136            int i = 0;
1137            int j = array.length - 1;
1138            double tmp;
1139            while (j > i) {
1140                tmp = array[j];
1141                array[j] = array[i];
1142                array[i] = tmp;
1143                j--;
1144                i++;
1145            }
1146        }
1147    
1148        /**
1149         * <p>Reverses the order of the given array.</p>
1150         * 
1151         * <p>This method does nothing for a <code>null</code> input array.</p>
1152         * 
1153         * @param array  the array to reverse, may be <code>null</code>
1154         */
1155        public static void reverse(float[] array) {
1156            if (array == null) {
1157                return;
1158            }
1159            int i = 0;
1160            int j = array.length - 1;
1161            float tmp;
1162            while (j > i) {
1163                tmp = array[j];
1164                array[j] = array[i];
1165                array[i] = tmp;
1166                j--;
1167                i++;
1168            }
1169        }
1170    
1171        /**
1172         * <p>Reverses the order of the given array.</p>
1173         * 
1174         * <p>This method does nothing for a <code>null</code> input array.</p>
1175         * 
1176         * @param array  the array to reverse, may be <code>null</code>
1177         */
1178        public static void reverse(boolean[] array) {
1179            if (array == null) {
1180                return;
1181            }
1182            int i = 0;
1183            int j = array.length - 1;
1184            boolean tmp;
1185            while (j > i) {
1186                tmp = array[j];
1187                array[j] = array[i];
1188                array[i] = tmp;
1189                j--;
1190                i++;
1191            }
1192        }
1193    
1194        // IndexOf search
1195        // ----------------------------------------------------------------------
1196        
1197        // Object IndexOf
1198        //-----------------------------------------------------------------------
1199        /**
1200         * <p>Finds the index of the given object in the array.</p>
1201         *
1202         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1203         * 
1204         * @param array  the array to search through for the object, may be <code>null</code>
1205         * @param objectToFind  the object to find, may be <code>null</code>
1206         * @return the index of the object within the array, 
1207         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1208         */
1209        public static int indexOf(Object[] array, Object objectToFind) {
1210            return indexOf(array, objectToFind, 0);
1211        }
1212    
1213        /**
1214         * <p>Finds the index of the given object in the array starting at the given index.</p>
1215         *
1216         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1217         *
1218         * <p>A negative startIndex is treated as zero. A startIndex larger than the array
1219         * length will return {@link #INDEX_NOT_FOUND} (<code>-1</code>).</p>
1220         * 
1221         * @param array  the array to search through for the object, may be <code>null</code>
1222         * @param objectToFind  the object to find, may be <code>null</code>
1223         * @param startIndex  the index to start searching at
1224         * @return the index of the object within the array starting at the index,
1225         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1226         */
1227        public static int indexOf(Object[] array, Object objectToFind, int startIndex) {
1228            if (array == null) {
1229                return INDEX_NOT_FOUND;
1230            }
1231            if (startIndex < 0) {
1232                startIndex = 0;
1233            }
1234            if (objectToFind == null) {
1235                for (int i = startIndex; i < array.length; i++) {
1236                    if (array[i] == null) {
1237                        return i;
1238                    }
1239                }
1240            } else {
1241                for (int i = startIndex; i < array.length; i++) {
1242                    if (objectToFind.equals(array[i])) {
1243                        return i;
1244                    }
1245                }
1246            }
1247            return INDEX_NOT_FOUND;
1248        }
1249    
1250        /**
1251         * <p>Finds the last index of the given object within the array.</p>
1252         *
1253         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1254         * 
1255         * @param array  the array to travers backwords looking for the object, may be <code>null</code>
1256         * @param objectToFind  the object to find, may be <code>null</code>
1257         * @return the last index of the object within the array,
1258         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1259         */
1260        public static int lastIndexOf(Object[] array, Object objectToFind) {
1261            return lastIndexOf(array, objectToFind, Integer.MAX_VALUE);
1262        }
1263    
1264        /**
1265         * <p>Finds the last index of the given object in the array starting at the given index.</p>
1266         *
1267         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1268         *
1269         * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} (<code>-1</code>). A startIndex larger than
1270         * the array length will search from the end of the array.</p>
1271         * 
1272         * @param array  the array to traverse for looking for the object, may be <code>null</code>
1273         * @param objectToFind  the object to find, may be <code>null</code>
1274         * @param startIndex  the start index to travers backwards from
1275         * @return the last index of the object within the array,
1276         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1277         */
1278        public static int lastIndexOf(Object[] array, Object objectToFind, int startIndex) {
1279            if (array == null) {
1280                return INDEX_NOT_FOUND;
1281            }
1282            if (startIndex < 0) {
1283                return INDEX_NOT_FOUND;
1284            } else if (startIndex >= array.length) {
1285                startIndex = array.length - 1;
1286            }
1287            if (objectToFind == null) {
1288                for (int i = startIndex; i >= 0; i--) {
1289                    if (array[i] == null) {
1290                        return i;
1291                    }
1292                }
1293            } else {
1294                for (int i = startIndex; i >= 0; i--) {
1295                    if (objectToFind.equals(array[i])) {
1296                        return i;
1297                    }
1298                }
1299            }
1300            return INDEX_NOT_FOUND;
1301        }
1302    
1303        /**
1304         * <p>Checks if the object is in the given array.</p>
1305         *
1306         * <p>The method returns <code>false</code> if a <code>null</code> array is passed in.</p>
1307         * 
1308         * @param array  the array to search through
1309         * @param objectToFind  the object to find
1310         * @return <code>true</code> if the array contains the object
1311         */
1312        public static boolean contains(Object[] array, Object objectToFind) {
1313            return indexOf(array, objectToFind) != INDEX_NOT_FOUND;
1314        }
1315    
1316        // long IndexOf
1317        //-----------------------------------------------------------------------
1318        /**
1319         * <p>Finds the index of the given value in the array.</p>
1320         *
1321         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1322         * 
1323         * @param array  the array to search through for the object, may be <code>null</code>
1324         * @param valueToFind  the value to find
1325         * @return the index of the value within the array,
1326         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1327         */
1328        public static int indexOf(long[] array, long valueToFind) {
1329            return indexOf(array, valueToFind, 0);
1330        }
1331    
1332        /**
1333         * <p>Finds the index of the given value in the array starting at the given index.</p>
1334         *
1335         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1336         *
1337         * <p>A negative startIndex is treated as zero. A startIndex larger than the array
1338         * length will return {@link #INDEX_NOT_FOUND} (<code>-1</code>).</p>
1339         * 
1340         * @param array  the array to search through for the object, may be <code>null</code>
1341         * @param valueToFind  the value to find
1342         * @param startIndex  the index to start searching at
1343         * @return the index of the value within the array,
1344         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1345         */
1346        public static int indexOf(long[] array, long valueToFind, int startIndex) {
1347            if (array == null) {
1348                return INDEX_NOT_FOUND;
1349            }
1350            if (startIndex < 0) {
1351                startIndex = 0;
1352            }
1353            for (int i = startIndex; i < array.length; i++) {
1354                if (valueToFind == array[i]) {
1355                    return i;
1356                }
1357            }
1358            return INDEX_NOT_FOUND;
1359        }
1360    
1361        /**
1362         * <p>Finds the last index of the given value within the array.</p>
1363         *
1364         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1365         * 
1366         * @param array  the array to travers backwords looking for the object, may be <code>null</code>
1367         * @param valueToFind  the object to find
1368         * @return the last index of the value within the array,
1369         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1370         */
1371        public static int lastIndexOf(long[] array, long valueToFind) {
1372            return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
1373        }
1374    
1375        /**
1376         * <p>Finds the last index of the given value in the array starting at the given index.</p>
1377         *
1378         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1379         *
1380         * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} (<code>-1</code>). A startIndex larger than the
1381         * array length will search from the end of the array.</p>
1382         * 
1383         * @param array  the array to traverse for looking for the object, may be <code>null</code>
1384         * @param valueToFind  the value to find
1385         * @param startIndex  the start index to travers backwards from
1386         * @return the last index of the value within the array,
1387         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1388         */
1389        public static int lastIndexOf(long[] array, long valueToFind, int startIndex) {
1390            if (array == null) {
1391                return INDEX_NOT_FOUND;
1392            }
1393            if (startIndex < 0) {
1394                return INDEX_NOT_FOUND;
1395            } else if (startIndex >= array.length) {
1396                startIndex = array.length - 1;
1397            }
1398            for (int i = startIndex; i >= 0; i--) {
1399                if (valueToFind == array[i]) {
1400                    return i;
1401                }
1402            }
1403            return INDEX_NOT_FOUND;
1404        }
1405    
1406        /**
1407         * <p>Checks if the value is in the given array.</p>
1408         *
1409         * <p>The method returns <code>false</code> if a <code>null</code> array is passed in.</p>
1410         * 
1411         * @param array  the array to search through
1412         * @param valueToFind  the value to find
1413         * @return <code>true</code> if the array contains the object
1414         */
1415        public static boolean contains(long[] array, long valueToFind) {
1416            return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
1417        }
1418    
1419        // int IndexOf
1420        //-----------------------------------------------------------------------
1421        /**
1422         * <p>Finds the index of the given value in the array.</p>
1423         *
1424         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1425         * 
1426         * @param array  the array to search through for the object, may be <code>null</code>
1427         * @param valueToFind  the value to find
1428         * @return the index of the value within the array,
1429         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1430         */
1431        public static int indexOf(int[] array, int valueToFind) {
1432            return indexOf(array, valueToFind, 0);
1433        }
1434    
1435        /**
1436         * <p>Finds the index of the given value in the array starting at the given index.</p>
1437         *
1438         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1439         *
1440         * <p>A negative startIndex is treated as zero. A startIndex larger than the array
1441         * length will return {@link #INDEX_NOT_FOUND} (<code>-1</code>).</p>
1442         * 
1443         * @param array  the array to search through for the object, may be <code>null</code>
1444         * @param valueToFind  the value to find
1445         * @param startIndex  the index to start searching at
1446         * @return the index of the value within the array,
1447         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1448         */
1449        public static int indexOf(int[] array, int valueToFind, int startIndex) {
1450            if (array == null) {
1451                return INDEX_NOT_FOUND;
1452            }
1453            if (startIndex < 0) {
1454                startIndex = 0;
1455            }
1456            for (int i = startIndex; i < array.length; i++) {
1457                if (valueToFind == array[i]) {
1458                    return i;
1459                }
1460            }
1461            return INDEX_NOT_FOUND;
1462        }
1463    
1464        /**
1465         * <p>Finds the last index of the given value within the array.</p>
1466         *
1467         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1468         * 
1469         * @param array  the array to travers backwords looking for the object, may be <code>null</code>
1470         * @param valueToFind  the object to find
1471         * @return the last index of the value within the array,
1472         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1473         */
1474        public static int lastIndexOf(int[] array, int valueToFind) {
1475            return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
1476        }
1477    
1478        /**
1479         * <p>Finds the last index of the given value in the array starting at the given index.</p>
1480         *
1481         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1482         *
1483         * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} (<code>-1</code>). A startIndex larger than the
1484         * array length will search from the end of the array.</p>
1485         * 
1486         * @param array  the array to traverse for looking for the object, may be <code>null</code>
1487         * @param valueToFind  the value to find
1488         * @param startIndex  the start index to travers backwards from
1489         * @return the last index of the value within the array,
1490         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1491         */
1492        public static int lastIndexOf(int[] array, int valueToFind, int startIndex) {
1493            if (array == null) {
1494                return INDEX_NOT_FOUND;
1495            }
1496            if (startIndex < 0) {
1497                return INDEX_NOT_FOUND;
1498            } else if (startIndex >= array.length) {
1499                startIndex = array.length - 1;
1500            }
1501            for (int i = startIndex; i >= 0; i--) {
1502                if (valueToFind == array[i]) {
1503                    return i;
1504                }
1505            }
1506            return INDEX_NOT_FOUND;
1507        }
1508    
1509        /**
1510         * <p>Checks if the value is in the given array.</p>
1511         *
1512         * <p>The method returns <code>false</code> if a <code>null</code> array is passed in.</p>
1513         * 
1514         * @param array  the array to search through
1515         * @param valueToFind  the value to find
1516         * @return <code>true</code> if the array contains the object
1517         */
1518        public static boolean contains(int[] array, int valueToFind) {
1519            return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
1520        }
1521    
1522        // short IndexOf
1523        //-----------------------------------------------------------------------
1524        /**
1525         * <p>Finds the index of the given value in the array.</p>
1526         *
1527         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1528         * 
1529         * @param array  the array to search through for the object, may be <code>null</code>
1530         * @param valueToFind  the value to find
1531         * @return the index of the value within the array,
1532         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1533         */
1534        public static int indexOf(short[] array, short valueToFind) {
1535            return indexOf(array, valueToFind, 0);
1536        }
1537    
1538        /**
1539         * <p>Finds the index of the given value in the array starting at the given index.</p>
1540         *
1541         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1542         *
1543         * <p>A negative startIndex is treated as zero. A startIndex larger than the array
1544         * length will return {@link #INDEX_NOT_FOUND} (<code>-1</code>).</p>
1545         * 
1546         * @param array  the array to search through for the object, may be <code>null</code>
1547         * @param valueToFind  the value to find
1548         * @param startIndex  the index to start searching at
1549         * @return the index of the value within the array,
1550         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1551         */
1552        public static int indexOf(short[] array, short valueToFind, int startIndex) {
1553            if (array == null) {
1554                return INDEX_NOT_FOUND;
1555            }
1556            if (startIndex < 0) {
1557                startIndex = 0;
1558            }
1559            for (int i = startIndex; i < array.length; i++) {
1560                if (valueToFind == array[i]) {
1561                    return i;
1562                }
1563            }
1564            return INDEX_NOT_FOUND;
1565        }
1566    
1567        /**
1568         * <p>Finds the last index of the given value within the array.</p>
1569         *
1570         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1571         * 
1572         * @param array  the array to travers backwords looking for the object, may be <code>null</code>
1573         * @param valueToFind  the object to find
1574         * @return the last index of the value within the array,
1575         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1576         */
1577        public static int lastIndexOf(short[] array, short valueToFind) {
1578            return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
1579        }
1580    
1581        /**
1582         * <p>Finds the last index of the given value in the array starting at the given index.</p>
1583         *
1584         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1585         *
1586         * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} (<code>-1</code>). A startIndex larger than the 
1587         * array length will search from the end of the array.</p>
1588         * 
1589         * @param array  the array to traverse for looking for the object, may be <code>null</code>
1590         * @param valueToFind  the value to find
1591         * @param startIndex  the start index to travers backwards from
1592         * @return the last index of the value within the array,
1593         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1594         */
1595        public static int lastIndexOf(short[] array, short valueToFind, int startIndex) {
1596            if (array == null) {
1597                return INDEX_NOT_FOUND;
1598            }
1599            if (startIndex < 0) {
1600                return INDEX_NOT_FOUND;
1601            } else if (startIndex >= array.length) {
1602                startIndex = array.length - 1;
1603            }
1604            for (int i = startIndex; i >= 0; i--) {
1605                if (valueToFind == array[i]) {
1606                    return i;
1607                }
1608            }
1609            return INDEX_NOT_FOUND;
1610        }
1611    
1612        /**
1613         * <p>Checks if the value is in the given array.</p>
1614         *
1615         * <p>The method returns <code>false</code> if a <code>null</code> array is passed in.</p>
1616         * 
1617         * @param array  the array to search through
1618         * @param valueToFind  the value to find
1619         * @return <code>true</code> if the array contains the object
1620         */
1621        public static boolean contains(short[] array, short valueToFind) {
1622            return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
1623        }
1624    
1625        // char IndexOf
1626        //-----------------------------------------------------------------------
1627        /**
1628         * <p>Finds the index of the given value in the array.</p>
1629         *
1630         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1631         * 
1632         * @param array  the array to search through for the object, may be <code>null</code>
1633         * @param valueToFind  the value to find
1634         * @return the index of the value within the array,
1635         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1636         * @since 2.1
1637         */
1638        public static int indexOf(char[] array, char valueToFind) {
1639            return indexOf(array, valueToFind, 0);
1640        }
1641    
1642        /**
1643         * <p>Finds the index of the given value in the array starting at the given index.</p>
1644         *
1645         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1646         *
1647         * <p>A negative startIndex is treated as zero. A startIndex larger than the array
1648         * length will return {@link #INDEX_NOT_FOUND} (<code>-1</code>).</p>
1649         * 
1650         * @param array  the array to search through for the object, may be <code>null</code>
1651         * @param valueToFind  the value to find
1652         * @param startIndex  the index to start searching at
1653         * @return the index of the value within the array,
1654         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1655         * @since 2.1
1656         */
1657        public static int indexOf(char[] array, char valueToFind, int startIndex) {
1658            if (array == null) {
1659                return INDEX_NOT_FOUND;
1660            }
1661            if (startIndex < 0) {
1662                startIndex = 0;
1663            }
1664            for (int i = startIndex; i < array.length; i++) {
1665                if (valueToFind == array[i]) {
1666                    return i;
1667                }
1668            }
1669            return INDEX_NOT_FOUND;
1670        }
1671    
1672        /**
1673         * <p>Finds the last index of the given value within the array.</p>
1674         *
1675         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1676         * 
1677         * @param array  the array to travers backwords looking for the object, may be <code>null</code>
1678         * @param valueToFind  the object to find
1679         * @return the last index of the value within the array,
1680         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1681         * @since 2.1
1682         */
1683        public static int lastIndexOf(char[] array, char valueToFind) {
1684            return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
1685        }
1686    
1687        /**
1688         * <p>Finds the last index of the given value in the array starting at the given index.</p>
1689         *
1690         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1691         *
1692         * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} (<code>-1</code>). A startIndex larger than the
1693         * array length will search from the end of the array.</p>
1694         * 
1695         * @param array  the array to traverse for looking for the object, may be <code>null</code>
1696         * @param valueToFind  the value to find
1697         * @param startIndex  the start index to travers backwards from
1698         * @return the last index of the value within the array,
1699         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1700         * @since 2.1
1701         */
1702        public static int lastIndexOf(char[] array, char valueToFind, int startIndex) {
1703            if (array == null) {
1704                return INDEX_NOT_FOUND;
1705            }
1706            if (startIndex < 0) {
1707                return INDEX_NOT_FOUND;
1708            } else if (startIndex >= array.length) {
1709                startIndex = array.length - 1;
1710            }
1711            for (int i = startIndex; i >= 0; i--) {
1712                if (valueToFind == array[i]) {
1713                    return i;
1714                }
1715            }
1716            return INDEX_NOT_FOUND;
1717        }
1718    
1719        /**
1720         * <p>Checks if the value is in the given array.</p>
1721         *
1722         * <p>The method returns <code>false</code> if a <code>null</code> array is passed in.</p>
1723         * 
1724         * @param array  the array to search through
1725         * @param valueToFind  the value to find
1726         * @return <code>true</code> if the array contains the object
1727         * @since 2.1
1728         */
1729        public static boolean contains(char[] array, char valueToFind) {
1730            return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
1731        }
1732    
1733        // byte IndexOf
1734        //-----------------------------------------------------------------------
1735        /**
1736         * <p>Finds the index of the given value in the array.</p>
1737         *
1738         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1739         * 
1740         * @param array  the array to search through for the object, may be <code>null</code>
1741         * @param valueToFind  the value to find
1742         * @return the index of the value within the array,
1743         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1744         */
1745        public static int indexOf(byte[] array, byte valueToFind) {
1746            return indexOf(array, valueToFind, 0);
1747        }
1748    
1749        /**
1750         * <p>Finds the index of the given value in the array starting at the given index.</p>
1751         *
1752         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1753         *
1754         * <p>A negative startIndex is treated as zero. A startIndex larger than the array
1755         * length will return {@link #INDEX_NOT_FOUND} (<code>-1</code>).</p>
1756         * 
1757         * @param array  the array to search through for the object, may be <code>null</code>
1758         * @param valueToFind  the value to find
1759         * @param startIndex  the index to start searching at
1760         * @return the index of the value within the array,
1761         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1762         */
1763        public static int indexOf(byte[] array, byte valueToFind, int startIndex) {
1764            if (array == null) {
1765                return INDEX_NOT_FOUND;
1766            }
1767            if (startIndex < 0) {
1768                startIndex = 0;
1769            }
1770            for (int i = startIndex; i < array.length; i++) {
1771                if (valueToFind == array[i]) {
1772                    return i;
1773                }
1774            }
1775            return INDEX_NOT_FOUND;
1776        }
1777    
1778        /**
1779         * <p>Finds the last index of the given value within the array.</p>
1780         *
1781         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1782         * 
1783         * @param array  the array to travers backwords looking for the object, may be <code>null</code>
1784         * @param valueToFind  the object to find
1785         * @return the last index of the value within the array,
1786         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1787         */
1788        public static int lastIndexOf(byte[] array, byte valueToFind) {
1789            return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
1790        }
1791    
1792        /**
1793         * <p>Finds the last index of the given value in the array starting at the given index.</p>
1794         *
1795         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1796         *
1797         * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} (<code>-1</code>). A startIndex larger than the 
1798         * array length will search from the end of the array.</p>
1799         * 
1800         * @param array  the array to traverse for looking for the object, may be <code>null</code>
1801         * @param valueToFind  the value to find
1802         * @param startIndex  the start index to travers backwards from
1803         * @return the last index of the value within the array,
1804         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1805         */
1806        public static int lastIndexOf(byte[] array, byte valueToFind, int startIndex) {
1807            if (array == null) {
1808                return INDEX_NOT_FOUND;
1809            }
1810            if (startIndex < 0) {
1811                return INDEX_NOT_FOUND;
1812            } else if (startIndex >= array.length) {
1813                startIndex = array.length - 1;
1814            }
1815            for (int i = startIndex; i >= 0; i--) {
1816                if (valueToFind == array[i]) {
1817                    return i;
1818                }
1819            }
1820            return INDEX_NOT_FOUND;
1821        }
1822    
1823        /**
1824         * <p>Checks if the value is in the given array.</p>
1825         *
1826         * <p>The method returns <code>false</code> if a <code>null</code> array is passed in.</p>
1827         * 
1828         * @param array  the array to search through
1829         * @param valueToFind  the value to find
1830         * @return <code>true</code> if the array contains the object
1831         */
1832        public static boolean contains(byte[] array, byte valueToFind) {
1833            return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
1834        }
1835    
1836        // double IndexOf
1837        //-----------------------------------------------------------------------
1838        /**
1839         * <p>Finds the index of the given value in the array.</p>
1840         *
1841         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1842         * 
1843         * @param array  the array to search through for the object, may be <code>null</code>
1844         * @param valueToFind  the value to find
1845         * @return the index of the value within the array,
1846         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1847         */
1848        public static int indexOf(double[] array, double valueToFind) {
1849            return indexOf(array, valueToFind, 0);
1850        }
1851    
1852        /**
1853         * <p>Finds the index of the given value within a given tolerance in the array.
1854         * This method will return the index of the first value which falls between the region
1855         * defined by valueToFind - tolerance and valueToFind + tolerance.</p>
1856         *
1857         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1858         * 
1859         * @param array  the array to search through for the object, may be <code>null</code>
1860         * @param valueToFind  the value to find
1861         * @param tolerance tolerance of the search
1862         * @return the index of the value within the array,
1863         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1864         */
1865        public static int indexOf(double[] array, double valueToFind, double tolerance) {
1866            return indexOf(array, valueToFind, 0, tolerance);
1867        }
1868    
1869        /**
1870         * <p>Finds the index of the given value in the array starting at the given index.</p>
1871         *
1872         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1873         *
1874         * <p>A negative startIndex is treated as zero. A startIndex larger than the array
1875         * length will return {@link #INDEX_NOT_FOUND} (<code>-1</code>).</p>
1876         * 
1877         * @param array  the array to search through for the object, may be <code>null</code>
1878         * @param valueToFind  the value to find
1879         * @param startIndex  the index to start searching at
1880         * @return the index of the value within the array,
1881         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1882         */
1883        public static int indexOf(double[] array, double valueToFind, int startIndex) {
1884            if (ArrayUtils.isEmpty(array)) {
1885                return INDEX_NOT_FOUND;
1886            }
1887            if (startIndex < 0) {
1888                startIndex = 0;
1889            }
1890            for (int i = startIndex; i < array.length; i++) {
1891                if (valueToFind == array[i]) {
1892                    return i;
1893                }
1894            }
1895            return INDEX_NOT_FOUND;
1896        }
1897    
1898        /**
1899         * <p>Finds the index of the given value in the array starting at the given index.
1900         * This method will return the index of the first value which falls between the region
1901         * defined by valueToFind - tolerance and valueToFind + tolerance.</p>
1902         *
1903         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1904         *
1905         * <p>A negative startIndex is treated as zero. A startIndex larger than the array
1906         * length will return {@link #INDEX_NOT_FOUND} (<code>-1</code>).</p>
1907         * 
1908         * @param array  the array to search through for the object, may be <code>null</code>
1909         * @param valueToFind  the value to find
1910         * @param startIndex  the index to start searching at
1911         * @param tolerance tolerance of the search
1912         * @return the index of the value within the array,
1913         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1914         */
1915        public static int indexOf(double[] array, double valueToFind, int startIndex, double tolerance) {
1916            if (ArrayUtils.isEmpty(array)) {
1917                return INDEX_NOT_FOUND;
1918            }
1919            if (startIndex < 0) {
1920                startIndex = 0;
1921            }
1922            double min = valueToFind - tolerance;
1923            double max = valueToFind + tolerance;
1924            for (int i = startIndex; i < array.length; i++) {
1925                if (array[i] >= min && array[i] <= max) {
1926                    return i;
1927                }
1928            }
1929            return INDEX_NOT_FOUND;
1930        }
1931    
1932        /**
1933         * <p>Finds the last index of the given value within the array.</p>
1934         *
1935         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1936         * 
1937         * @param array  the array to travers backwords looking for the object, may be <code>null</code>
1938         * @param valueToFind  the object to find
1939         * @return the last index of the value within the array,
1940         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1941         */
1942        public static int lastIndexOf(double[] array, double valueToFind) {
1943            return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
1944        }
1945    
1946        /**
1947         * <p>Finds the last index of the given value within a given tolerance in the array.
1948         * This method will return the index of the last value which falls between the region
1949         * defined by valueToFind - tolerance and valueToFind + tolerance.</p>
1950         *
1951         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1952         * 
1953         * @param array  the array to search through for the object, may be <code>null</code>
1954         * @param valueToFind  the value to find
1955         * @param tolerance tolerance of the search
1956         * @return the index of the value within the array,
1957         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1958         */
1959        public static int lastIndexOf(double[] array, double valueToFind, double tolerance) {
1960            return lastIndexOf(array, valueToFind, Integer.MAX_VALUE, tolerance);
1961        }
1962    
1963        /**
1964         * <p>Finds the last index of the given value in the array starting at the given index.</p>
1965         *
1966         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1967         *
1968         * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} (<code>-1</code>). A startIndex larger than the 
1969         * array length will search from the end of the array.</p>
1970         * 
1971         * @param array  the array to traverse for looking for the object, may be <code>null</code>
1972         * @param valueToFind  the value to find
1973         * @param startIndex  the start index to travers backwards from
1974         * @return the last index of the value within the array,
1975         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1976         */
1977        public static int lastIndexOf(double[] array, double valueToFind, int startIndex) {
1978            if (ArrayUtils.isEmpty(array)) {
1979                return INDEX_NOT_FOUND;
1980            }
1981            if (startIndex < 0) {
1982                return INDEX_NOT_FOUND;
1983            } else if (startIndex >= array.length) {
1984                startIndex = array.length - 1;
1985            }
1986            for (int i = startIndex; i >= 0; i--) {
1987                if (valueToFind == array[i]) {
1988                    return i;
1989                }
1990            }
1991            return INDEX_NOT_FOUND;
1992        }
1993    
1994        /**
1995         * <p>Finds the last index of the given value in the array starting at the given index.
1996         * This method will return the index of the last value which falls between the region
1997         * defined by valueToFind - tolerance and valueToFind + tolerance.</p>
1998         *
1999         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
2000         *
2001         * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} (<code>-1</code>). A startIndex larger than the 
2002         * array length will search from the end of the array.</p>
2003         * 
2004         * @param array  the array to traverse for looking for the object, may be <code>null</code>
2005         * @param valueToFind  the value to find
2006         * @param startIndex  the start index to travers backwards from
2007         * @param tolerance  search for value within plus/minus this amount
2008         * @return the last index of the value within the array,
2009         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
2010         */
2011        public static int lastIndexOf(double[] array, double valueToFind, int startIndex, double tolerance) {
2012            if (ArrayUtils.isEmpty(array)) {
2013                return INDEX_NOT_FOUND;
2014            }
2015            if (startIndex < 0) {
2016                return INDEX_NOT_FOUND;
2017            } else if (startIndex >= array.length) {
2018                startIndex = array.length - 1;
2019            }
2020            double min = valueToFind - tolerance;
2021            double max = valueToFind + tolerance;
2022            for (int i = startIndex; i >= 0; i--) {
2023                if (array[i] >= min && array[i] <= max) {
2024                    return i;
2025                }
2026            }
2027            return INDEX_NOT_FOUND;
2028        }
2029    
2030        /**
2031         * <p>Checks if the value is in the given array.</p>
2032         *
2033         * <p>The method returns <code>false</code> if a <code>null</code> array is passed in.</p>
2034         * 
2035         * @param array  the array to search through
2036         * @param valueToFind  the value to find
2037         * @return <code>true</code> if the array contains the object
2038         */
2039        public static boolean contains(double[] array, double valueToFind) {
2040            return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
2041        }
2042    
2043        /**
2044         * <p>Checks if a value falling within the given tolerance is in the
2045         * given array.  If the array contains a value within the inclusive range 
2046         * defined by (value - tolerance) to (value + tolerance).</p>
2047         *
2048         * <p>The method returns <code>false</code> if a <code>null</code> array
2049         * is passed in.</p>
2050         *
2051         * @param array  the array to search
2052         * @param valueToFind  the value to find
2053         * @param tolerance  the array contains the tolerance of the search
2054         * @return true if value falling within tolerance is in array
2055         */
2056        public static boolean contains(double[] array, double valueToFind, double tolerance) {
2057            return indexOf(array, valueToFind, 0, tolerance) != INDEX_NOT_FOUND;
2058        }
2059    
2060        // float IndexOf
2061        //-----------------------------------------------------------------------
2062        /**
2063         * <p>Finds the index of the given value in the array.</p>
2064         *
2065         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
2066         * 
2067         * @param array  the array to search through for the object, may be <code>null</code>
2068         * @param valueToFind  the value to find
2069         * @return the index of the value within the array,
2070         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
2071         */
2072        public static int indexOf(float[] array, float valueToFind) {
2073            return indexOf(array, valueToFind, 0);
2074        }
2075    
2076        /**
2077         * <p>Finds the index of the given value in the array starting at the given index.</p>
2078         *
2079         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
2080         *
2081         * <p>A negative startIndex is treated as zero. A startIndex larger than the array
2082         * length will return {@link #INDEX_NOT_FOUND} (<code>-1</code>).</p>
2083         * 
2084         * @param array  the array to search through for the object, may be <code>null</code>
2085         * @param valueToFind  the value to find
2086         * @param startIndex  the index to start searching at
2087         * @return the index of the value within the array,
2088         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
2089         */
2090        public static int indexOf(float[] array, float valueToFind, int startIndex) {
2091            if (ArrayUtils.isEmpty(array)) {
2092                return INDEX_NOT_FOUND;
2093            }
2094            if (startIndex < 0) {
2095                startIndex = 0;
2096            }
2097            for (int i = startIndex; i < array.length; i++) {
2098                if (valueToFind == array[i]) {
2099                    return i;
2100                }
2101            }
2102            return INDEX_NOT_FOUND;
2103        }
2104    
2105        /**
2106         * <p>Finds the last index of the given value within the array.</p>
2107         *
2108         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
2109         * 
2110         * @param array  the array to travers backwords looking for the object, may be <code>null</code>
2111         * @param valueToFind  the object to find
2112         * @return the last index of the value within the array,
2113         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
2114         */
2115        public static int lastIndexOf(float[] array, float valueToFind) {
2116            return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
2117        }
2118    
2119        /**
2120         * <p>Finds the last index of the given value in the array starting at the given index.</p>
2121         *
2122         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
2123         *
2124         * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} (<code>-1</code>). A startIndex larger than the 
2125         * array length will search from the end of the array.</p>
2126         * 
2127         * @param array  the array to traverse for looking for the object, may be <code>null</code>
2128         * @param valueToFind  the value to find
2129         * @param startIndex  the start index to travers backwards from
2130         * @return the last index of the value within the array,
2131         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
2132         */
2133        public static int lastIndexOf(float[] array, float valueToFind, int startIndex) {
2134            if (ArrayUtils.isEmpty(array)) {
2135                return INDEX_NOT_FOUND;
2136            }
2137            if (startIndex < 0) {
2138                return INDEX_NOT_FOUND;
2139            } else if (startIndex >= array.length) {
2140                startIndex = array.length - 1;
2141            }
2142            for (int i = startIndex; i >= 0; i--) {
2143                if (valueToFind == array[i]) {
2144                    return i;
2145                }
2146            }
2147            return INDEX_NOT_FOUND;
2148        }
2149    
2150        /**
2151         * <p>Checks if the value is in the given array.</p>
2152         *
2153         * <p>The method returns <code>false</code> if a <code>null</code> array is passed in.</p>
2154         * 
2155         * @param array  the array to search through
2156         * @param valueToFind  the value to find
2157         * @return <code>true</code> if the array contains the object
2158         */
2159        public static boolean contains(float[] array, float valueToFind) {
2160            return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
2161        }
2162    
2163        // boolean IndexOf
2164        //-----------------------------------------------------------------------
2165        /**
2166         * <p>Finds the index of the given value in the array.</p>
2167         *
2168         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
2169         * 
2170         * @param array  the array to search through for the object, may be <code>null</code>
2171         * @param valueToFind  the value to find
2172         * @return the index of the value within the array,
2173         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
2174         */
2175        public static int indexOf(boolean[] array, boolean valueToFind) {
2176            return indexOf(array, valueToFind, 0);
2177        }
2178    
2179        /**
2180         * <p>Finds the index of the given value in the array starting at the given index.</p>
2181         *
2182         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
2183         *
2184         * <p>A negative startIndex is treated as zero. A startIndex larger than the array
2185         * length will return {@link #INDEX_NOT_FOUND} (<code>-1</code>).</p>
2186         * 
2187         * @param array  the array to search through for the object, may be <code>null</code>
2188         * @param valueToFind  the value to find
2189         * @param startIndex  the index to start searching at
2190         * @return the index of the value within the array,
2191         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code>
2192         *  array input
2193         */
2194        public static int indexOf(boolean[] array, boolean valueToFind, int startIndex) {
2195            if (ArrayUtils.isEmpty(array)) {
2196                return INDEX_NOT_FOUND;
2197            }
2198            if (startIndex < 0) {
2199                startIndex = 0;
2200            }
2201            for (int i = startIndex; i < array.length; i++) {
2202                if (valueToFind == array[i]) {
2203                    return i;
2204                }
2205            }
2206            return INDEX_NOT_FOUND;
2207        }
2208    
2209        /**
2210         * <p>Finds the last index of the given value within the array.</p>
2211         *
2212         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) if 
2213         * <code>null</code> array input.</p>
2214         * 
2215         * @param array  the array to travers backwords looking for the object, may be <code>null</code>
2216         * @param valueToFind  the object to find
2217         * @return the last index of the value within the array,
2218         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
2219         */
2220        public static int lastIndexOf(boolean[] array, boolean valueToFind) {
2221            return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
2222        }
2223    
2224        /**
2225         * <p>Finds the last index of the given value in the array starting at the given index.</p>
2226         *
2227         * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
2228         *
2229         * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} (<code>-1</code>). A startIndex larger than 
2230         * the array length will search from the end of the array.</p>
2231         * 
2232         * @param array  the array to traverse for looking for the object, may be <code>null</code>
2233         * @param valueToFind  the value to find
2234         * @param startIndex  the start index to travers backwards from
2235         * @return the last index of the value within the array,
2236         *  {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
2237         */
2238        public static int lastIndexOf(boolean[] array, boolean valueToFind, int startIndex) {
2239            if (ArrayUtils.isEmpty(array)) {
2240                return INDEX_NOT_FOUND;
2241            }
2242            if (startIndex < 0) {
2243                return INDEX_NOT_FOUND;
2244            } else if (startIndex >= array.length) {
2245                startIndex = array.length - 1;
2246            }
2247            for (int i = startIndex; i >= 0; i--) {
2248                if (valueToFind == array[i]) {
2249                    return i;
2250                }
2251            }
2252            return INDEX_NOT_FOUND;
2253        }
2254    
2255        /**
2256         * <p>Checks if the value is in the given array.</p>
2257         *
2258         * <p>The method returns <code>false</code> if a <code>null</code> array is passed in.</p>
2259         * 
2260         * @param array  the array to search through
2261         * @param valueToFind  the value to find
2262         * @return <code>true</code> if the array contains the object
2263         */
2264        public static boolean contains(boolean[] array, boolean valueToFind) {
2265            return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
2266        }
2267    
2268        // Primitive/Object array converters
2269        // ----------------------------------------------------------------------
2270    
2271        // Character array converters
2272        // ----------------------------------------------------------------------
2273        /**
2274         * <p>Converts an array of object Characters to primitives.</p>
2275         *
2276         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
2277         * 
2278         * @param array  a <code>Character</code> array, may be <code>null</code>
2279         * @return a <code>char</code> array, <code>null</code> if null array input
2280         * @throws NullPointerException if array content is <code>null</code>
2281         */
2282        public static char[] toPrimitive(Character[] array) {
2283            if (array == null) {
2284                return null;
2285            } else if (array.length == 0) {
2286                return EMPTY_CHAR_ARRAY;
2287            }
2288            final char[] result = new char[array.length];
2289            for (int i = 0; i < array.length; i++) {
2290                result[i] = array[i].charValue();
2291            }
2292            return result;
2293        }
2294    
2295        /**
2296         * <p>Converts an array of object Character to primitives handling <code>null</code>.</p>
2297         * 
2298         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
2299         * 
2300         * @param array  a <code>Character</code> array, may be <code>null</code>
2301         * @param valueForNull  the value to insert if <code>null</code> found
2302         * @return a <code>char</code> array, <code>null</code> if null array input
2303         */
2304        public static char[] toPrimitive(Character[] array, char valueForNull) {
2305            if (array == null) {
2306                return null;
2307            } else if (array.length == 0) {
2308                return EMPTY_CHAR_ARRAY;
2309            }
2310            final char[] result = new char[array.length];
2311            for (int i = 0; i < array.length; i++) {
2312                Character b = array[i];
2313                result[i] = (b == null ? valueForNull : b.charValue());
2314            }
2315            return result;
2316        }
2317        
2318        /**
2319         * <p>Converts an array of primitive chars to objects.</p>
2320         *
2321         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
2322         * 
2323         * @param array a <code>char</code> array
2324         * @return a <code>Character</code> array, <code>null</code> if null array input
2325         */
2326        public static Character[] toObject(char[] array) {
2327            if (array == null) {
2328                return null;
2329            } else if (array.length == 0) {
2330                return EMPTY_CHARACTER_OBJECT_ARRAY;
2331            }
2332            final Character[] result = new Character[array.length];
2333            for (int i = 0; i < array.length; i++) {
2334                result[i] = new Character(array[i]);
2335            }
2336            return result;
2337         }    
2338        
2339        // Long array converters
2340        // ----------------------------------------------------------------------
2341        /**
2342         * <p>Converts an array of object Longs to primitives.</p>
2343         *
2344         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
2345         * 
2346         * @param array  a <code>Long</code> array, may be <code>null</code>
2347         * @return a <code>long</code> array, <code>null</code> if null array input
2348         * @throws NullPointerException if array content is <code>null</code>
2349         */
2350        public static long[] toPrimitive(Long[] array) {
2351            if (array == null) {
2352                return null;
2353            } else if (array.length == 0) {
2354                return EMPTY_LONG_ARRAY;
2355            }
2356            final long[] result = new long[array.length];
2357            for (int i = 0; i < array.length; i++) {
2358                result[i] = array[i].longValue();
2359            }
2360            return result;
2361        }
2362        
2363        /**
2364         * <p>Converts an array of object Long to primitives handling <code>null</code>.</p>
2365         * 
2366         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
2367         * 
2368         * @param array  a <code>Long</code> array, may be <code>null</code>
2369         * @param valueForNull  the value to insert if <code>null</code> found
2370         * @return a <code>long</code> array, <code>null</code> if null array input
2371         */
2372        public static long[] toPrimitive(Long[] array, long valueForNull) {
2373            if (array == null) {
2374                return null;
2375            } else if (array.length == 0) {
2376                return EMPTY_LONG_ARRAY;
2377            }
2378            final long[] result = new long[array.length];
2379            for (int i = 0; i < array.length; i++) {
2380                Long b = array[i];
2381                result[i] = (b == null ? valueForNull : b.longValue());
2382            }
2383            return result;
2384        }
2385        
2386        /**
2387         * <p>Converts an array of primitive longs to objects.</p>
2388         *
2389         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
2390         * 
2391         * @param array  a <code>long</code> array
2392         * @return a <code>Long</code> array, <code>null</code> if null array input
2393         */
2394        public static Long[] toObject(long[] array) {
2395            if (array == null) {
2396                return null;
2397            } else if (array.length == 0) {
2398                return EMPTY_LONG_OBJECT_ARRAY;
2399            }
2400            final Long[] result = new Long[array.length];
2401            for (int i = 0; i < array.length; i++) {
2402                result[i] = new Long(array[i]);
2403            }
2404            return result;
2405        }
2406    
2407        // Int array converters
2408        // ----------------------------------------------------------------------
2409        /**
2410         * <p>Converts an array of object Integers to primitives.</p>
2411         *
2412         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
2413         * 
2414         * @param array  a <code>Integer</code> array, may be <code>null</code>
2415         * @return an <code>int</code> array, <code>null</code> if null array input
2416         * @throws NullPointerException if array content is <code>null</code>
2417         */
2418        public static int[] toPrimitive(Integer[] array) {
2419            if (array == null) {
2420                return null;
2421            } else if (array.length == 0) {
2422                return EMPTY_INT_ARRAY;
2423            }
2424            final int[] result = new int[array.length];
2425            for (int i = 0; i < array.length; i++) {
2426                result[i] = array[i].intValue();
2427            }
2428            return result;
2429        }
2430    
2431        /**
2432         * <p>Converts an array of object Integer to primitives handling <code>null</code>.</p>
2433         * 
2434         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
2435         * 
2436         * @param array  a <code>Integer</code> array, may be <code>null</code>
2437         * @param valueForNull  the value to insert if <code>null</code> found
2438         * @return an <code>int</code> array, <code>null</code> if null array input
2439         */
2440        public static int[] toPrimitive(Integer[] array, int valueForNull) {
2441            if (array == null) {
2442                return null;
2443            } else if (array.length == 0) {
2444                return EMPTY_INT_ARRAY;
2445            }
2446            final int[] result = new int[array.length];
2447            for (int i = 0; i < array.length; i++) {
2448                Integer b = array[i];
2449                result[i] = (b == null ? valueForNull : b.intValue());
2450            }
2451            return result;
2452        }
2453    
2454        /**
2455         * <p>Converts an array of primitive ints to objects.</p>
2456         *
2457         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
2458         * 
2459         * @param array  an <code>int</code> array
2460         * @return an <code>Integer</code> array, <code>null</code> if null array input
2461         */
2462        public static Integer[] toObject(int[] array) {
2463            if (array == null) {
2464                return null;
2465            } else if (array.length == 0) {
2466                return EMPTY_INTEGER_OBJECT_ARRAY;
2467            }
2468            final Integer[] result = new Integer[array.length];
2469            for (int i = 0; i < array.length; i++) {
2470                result[i] = new Integer(array[i]);
2471            }
2472            return result;
2473        }
2474        
2475        // Short array converters
2476        // ----------------------------------------------------------------------
2477        /**
2478         * <p>Converts an array of object Shorts to primitives.</p>
2479         *
2480         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
2481         * 
2482         * @param array  a <code>Short</code> array, may be <code>null</code>
2483         * @return a <code>byte</code> array, <code>null</code> if null array input
2484         * @throws NullPointerException if array content is <code>null</code>
2485         */
2486        public static short[] toPrimitive(Short[] array) {
2487            if (array == null) {
2488                return null;
2489            } else if (array.length == 0) {
2490                return EMPTY_SHORT_ARRAY;
2491            }
2492            final short[] result = new short[array.length];
2493            for (int i = 0; i < array.length; i++) {
2494                result[i] = array[i].shortValue();
2495            }
2496            return result;
2497        }
2498    
2499        /**
2500         * <p>Converts an array of object Short to primitives handling <code>null</code>.</p>
2501         * 
2502         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
2503         * 
2504         * @param array  a <code>Short</code> array, may be <code>null</code>
2505         * @param valueForNull  the value to insert if <code>null</code> found
2506         * @return a <code>byte</code> array, <code>null</code> if null array input
2507         */
2508        public static short[] toPrimitive(Short[] array, short valueForNull) {
2509            if (array == null) {
2510                return null;
2511            } else if (array.length == 0) {
2512                return EMPTY_SHORT_ARRAY;
2513            }
2514            final short[] result = new short[array.length];
2515            for (int i = 0; i < array.length; i++) {
2516                Short b = array[i];
2517                result[i] = (b == null ? valueForNull : b.shortValue());
2518            }
2519            return result;
2520        }
2521    
2522        /**
2523         * <p>Converts an array of primitive shorts to objects.</p>
2524         *
2525         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
2526         * 
2527         * @param array  a <code>short</code> array
2528         * @return a <code>Short</code> array, <code>null</code> if null array input
2529         */
2530        public static Short[] toObject(short[] array) {
2531            if (array == null) {
2532                return null;
2533            } else if (array.length == 0) {
2534                return EMPTY_SHORT_OBJECT_ARRAY;
2535            }
2536            final Short[] result = new Short[array.length];
2537            for (int i = 0; i < array.length; i++) {
2538                result[i] = new Short(array[i]);
2539            }
2540            return result;
2541        }    
2542    
2543        // Byte array converters
2544        // ----------------------------------------------------------------------
2545        /**
2546         * <p>Converts an array of object Bytes to primitives.</p>
2547         *
2548         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
2549         * 
2550         * @param array  a <code>Byte</code> array, may be <code>null</code>
2551         * @return a <code>byte</code> array, <code>null</code> if null array input
2552         * @throws NullPointerException if array content is <code>null</code>
2553         */
2554        public static byte[] toPrimitive(Byte[] array) {
2555            if (array == null) {
2556                return null;
2557            } else if (array.length == 0) {
2558                return EMPTY_BYTE_ARRAY;
2559            }
2560            final byte[] result = new byte[array.length];
2561            for (int i = 0; i < array.length; i++) {
2562                result[i] = array[i].byteValue();
2563            }
2564            return result;
2565        }
2566    
2567        /**
2568         * <p>Converts an array of object Bytes to primitives handling <code>null</code>.</p>
2569         * 
2570         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
2571         * 
2572         * @param array  a <code>Byte</code> array, may be <code>null</code>
2573         * @param valueForNull  the value to insert if <code>null</code> found
2574         * @return a <code>byte</code> array, <code>null</code> if null array input
2575         */
2576        public static byte[] toPrimitive(Byte[] array, byte valueForNull) {
2577            if (array == null) {
2578                return null;
2579            } else if (array.length == 0) {
2580                return EMPTY_BYTE_ARRAY;
2581            }
2582            final byte[] result = new byte[array.length];
2583            for (int i = 0; i < array.length; i++) {
2584                Byte b = array[i];
2585                result[i] = (b == null ? valueForNull : b.byteValue());
2586            }
2587            return result;
2588        }
2589    
2590        /**
2591         * <p>Converts an array of primitive bytes to objects.</p>
2592         *
2593         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
2594         * 
2595         * @param array  a <code>byte</code> array
2596         * @return a <code>Byte</code> array, <code>null</code> if null array input
2597         */
2598        public static Byte[] toObject(byte[] array) {
2599            if (array == null) {
2600                return null;
2601            } else if (array.length == 0) {
2602                return EMPTY_BYTE_OBJECT_ARRAY;
2603            }
2604            final Byte[] result = new Byte[array.length];
2605            for (int i = 0; i < array.length; i++) {
2606                result[i] = new Byte(array[i]);
2607            }
2608            return result;
2609        }  
2610        
2611        // Double array converters
2612        // ----------------------------------------------------------------------
2613        /**
2614         * <p>Converts an array of object Doubles to primitives.</p>
2615         *
2616         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
2617         * 
2618         * @param array  a <code>Double</code> array, may be <code>null</code>
2619         * @return a <code>double</code> array, <code>null</code> if null array input
2620         * @throws NullPointerException if array content is <code>null</code>
2621         */
2622        public static double[] toPrimitive(Double[] array) {
2623            if (array == null) {
2624                return null;
2625            } else if (array.length == 0) {
2626                return EMPTY_DOUBLE_ARRAY;
2627            }
2628            final double[] result = new double[array.length];
2629            for (int i = 0; i < array.length; i++) {
2630                result[i] = array[i].doubleValue();
2631            }
2632            return result;
2633        }
2634    
2635        /**
2636         * <p>Converts an array of object Doubles to primitives handling <code>null</code>.</p>
2637         * 
2638         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
2639         * 
2640         * @param array  a <code>Double</code> array, may be <code>null</code>
2641         * @param valueForNull  the value to insert if <code>null</code> found
2642         * @return a <code>double</code> array, <code>null</code> if null array input
2643         */
2644        public static double[] toPrimitive(Double[] array, double valueForNull) {
2645            if (array == null) {
2646                return null;
2647            } else if (array.length == 0) {
2648                return EMPTY_DOUBLE_ARRAY;
2649            }
2650            final double[] result = new double[array.length];
2651            for (int i = 0; i < array.length; i++) {
2652                Double b = array[i];
2653                result[i] = (b == null ? valueForNull : b.doubleValue());
2654            }
2655            return result;
2656        }
2657    
2658        /**
2659         * <p>Converts an array of primitive doubles to objects.</p>
2660         *
2661         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
2662         * 
2663         * @param array  a <code>double</code> array
2664         * @return a <code>Double</code> array, <code>null</code> if null array input
2665         */
2666        public static Double[] toObject(double[] array) {
2667            if (array == null) {
2668                return null;
2669            } else if (array.length == 0) {
2670                return EMPTY_DOUBLE_OBJECT_ARRAY;
2671            }
2672            final Double[] result = new Double[array.length];
2673            for (int i = 0; i < array.length; i++) {
2674                result[i] = new Double(array[i]);
2675            }
2676            return result;
2677        }
2678    
2679        //   Float array converters
2680        // ----------------------------------------------------------------------
2681        /**
2682         * <p>Converts an array of object Floats to primitives.</p>
2683         *
2684         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
2685         * 
2686         * @param array  a <code>Float</code> array, may be <code>null</code>
2687         * @return a <code>float</code> array, <code>null</code> if null array input
2688         * @throws NullPointerException if array content is <code>null</code>
2689         */
2690        public static float[] toPrimitive(Float[] array) {
2691            if (array == null) {
2692                return null;
2693            } else if (array.length == 0) {
2694                return EMPTY_FLOAT_ARRAY;
2695            }
2696            final float[] result = new float[array.length];
2697            for (int i = 0; i < array.length; i++) {
2698                result[i] = array[i].floatValue();
2699            }
2700            return result;
2701        }
2702    
2703        /**
2704         * <p>Converts an array of object Floats to primitives handling <code>null</code>.</p>
2705         * 
2706         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
2707         * 
2708         * @param array  a <code>Float</code> array, may be <code>null</code>
2709         * @param valueForNull  the value to insert if <code>null</code> found
2710         * @return a <code>float</code> array, <code>null</code> if null array input
2711         */
2712        public static float[] toPrimitive(Float[] array, float valueForNull) {
2713            if (array == null) {
2714                return null;
2715            } else if (array.length == 0) {
2716                return EMPTY_FLOAT_ARRAY;
2717            }
2718            final float[] result = new float[array.length];
2719            for (int i = 0; i < array.length; i++) {
2720                Float b = array[i];
2721                result[i] = (b == null ? valueForNull : b.floatValue());
2722            }
2723            return result;
2724        }
2725    
2726        /**
2727         * <p>Converts an array of primitive floats to objects.</p>
2728         *
2729         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
2730         * 
2731         * @param array  a <code>float</code> array
2732         * @return a <code>Float</code> array, <code>null</code> if null array input
2733         */
2734        public static Float[] toObject(float[] array) {
2735            if (array == null) {
2736                return null;
2737            } else if (array.length == 0) {
2738                return EMPTY_FLOAT_OBJECT_ARRAY;
2739            }
2740            final Float[] result = new Float[array.length];
2741            for (int i = 0; i < array.length; i++) {
2742                result[i] = new Float(array[i]);
2743            }
2744            return result;
2745        }
2746    
2747        // Boolean array converters
2748        // ----------------------------------------------------------------------
2749        /**
2750         * <p>Converts an array of object Booleans to primitives.</p>
2751         *
2752         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
2753         * 
2754         * @param array  a <code>Boolean</code> array, may be <code>null</code>
2755         * @return a <code>boolean</code> array, <code>null</code> if null array input
2756         * @throws NullPointerException if array content is <code>null</code>
2757         */
2758        public static boolean[] toPrimitive(Boolean[] array) {
2759            if (array == null) {
2760                return null;
2761            } else if (array.length == 0) {
2762                return EMPTY_BOOLEAN_ARRAY;
2763            }
2764            final boolean[] result = new boolean[array.length];
2765            for (int i = 0; i < array.length; i++) {
2766                result[i] = array[i].booleanValue();
2767            }
2768            return result;
2769        }
2770    
2771        /**
2772         * <p>Converts an array of object Booleans to primitives handling <code>null</code>.</p>
2773         * 
2774         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
2775         * 
2776         * @param array  a <code>Boolean</code> array, may be <code>null</code>
2777         * @param valueForNull  the value to insert if <code>null</code> found
2778         * @return a <code>boolean</code> array, <code>null</code> if null array input
2779         */
2780        public static boolean[] toPrimitive(Boolean[] array, boolean valueForNull) {
2781            if (array == null) {
2782                return null;
2783            } else if (array.length == 0) {
2784                return EMPTY_BOOLEAN_ARRAY;
2785            }
2786            final boolean[] result = new boolean[array.length];
2787            for (int i = 0; i < array.length; i++) {
2788                Boolean b = array[i];
2789                result[i] = (b == null ? valueForNull : b.booleanValue());
2790            }
2791            return result;
2792        }
2793    
2794        /**
2795         * <p>Converts an array of primitive booleans to objects.</p>
2796         *
2797         * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
2798         * 
2799         * @param array  a <code>boolean</code> array
2800         * @return a <code>Boolean</code> array, <code>null</code> if null array input
2801         */
2802        public static Boolean[] toObject(boolean[] array) {
2803            if (array == null) {
2804                return null;
2805            } else if (array.length == 0) {
2806                return EMPTY_BOOLEAN_OBJECT_ARRAY;
2807            }
2808            final Boolean[] result = new Boolean[array.length];
2809            for (int i = 0; i < array.length; i++) {
2810                result[i] = (array[i] ? Boolean.TRUE : Boolean.FALSE);
2811            }
2812            return result;
2813        }
2814    
2815        // ----------------------------------------------------------------------
2816        /**
2817         * <p>Checks if an array of Objects is empty or <code>null</code>.</p>
2818         *
2819         * @param array  the array to test
2820         * @return <code>true</code> if the array is empty or <code>null</code>
2821         * @since 2.1
2822         */
2823        public static boolean isEmpty(Object[] array) {
2824            if (array == null || array.length == 0) {
2825                return true;
2826            }
2827            return false;
2828        }
2829    
2830        /**
2831         * <p>Checks if an array of primitive longs is empty or <code>null</code>.</p>
2832         *
2833         * @param array  the array to test
2834         * @return <code>true</code> if the array is empty or <code>null</code>
2835         * @since 2.1
2836         */
2837        public static boolean isEmpty(long[] array) {
2838            if (array == null || array.length == 0) {
2839                return true;
2840            }
2841            return false;
2842        }
2843    
2844        /**
2845         * <p>Checks if an array of primitive ints is empty or <code>null</code>.</p>
2846         *
2847         * @param array  the array to test
2848         * @return <code>true</code> if the array is empty or <code>null</code>
2849         * @since 2.1
2850         */
2851        public static boolean isEmpty(int[] array) {
2852            if (array == null || array.length == 0) {
2853                return true;
2854            }
2855            return false;
2856        }
2857    
2858        /**
2859         * <p>Checks if an array of primitive shorts is empty or <code>null</code>.</p>
2860         *
2861         * @param array  the array to test
2862         * @return <code>true</code> if the array is empty or <code>null</code>
2863         * @since 2.1
2864         */
2865        public static boolean isEmpty(short[] array) {
2866            if (array == null || array.length == 0) {
2867                return true;
2868            }
2869            return false;
2870        }
2871    
2872        /**
2873         * <p>Checks if an array of primitive chars is empty or <code>null</code>.</p>
2874         *
2875         * @param array  the array to test
2876         * @return <code>true</code> if the array is empty or <code>null</code>
2877         * @since 2.1
2878         */
2879        public static boolean isEmpty(char[] array) {
2880            if (array == null || array.length == 0) {
2881                return true;
2882            }
2883            return false;
2884        }
2885    
2886        /**
2887         * <p>Checks if an array of primitive bytes is empty or <code>null</code>.</p>
2888         *
2889         * @param array  the array to test
2890         * @return <code>true</code> if the array is empty or <code>null</code>
2891         * @since 2.1
2892         */
2893        public static boolean isEmpty(byte[] array) {
2894            if (array == null || array.length == 0) {
2895                return true;
2896            }
2897            return false;
2898        }
2899    
2900        /**
2901         * <p>Checks if an array of primitive doubles is empty or <code>null</code>.</p>
2902         *
2903         * @param array  the array to test
2904         * @return <code>true</code> if the array is empty or <code>null</code>
2905         * @since 2.1
2906         */
2907        public static boolean isEmpty(double[] array) {
2908            if (array == null || array.length == 0) {
2909                return true;
2910            }
2911            return false;
2912        }
2913    
2914        /**
2915         * <p>Checks if an array of primitive floats is empty or <code>null</code>.</p>
2916         *
2917         * @param array  the array to test
2918         * @return <code>true</code> if the array is empty or <code>null</code>
2919         * @since 2.1
2920         */
2921        public static boolean isEmpty(float[] array) {
2922            if (array == null || array.length == 0) {
2923                return true;
2924            }
2925            return false;
2926        }
2927    
2928        /**
2929         * <p>Checks if an array of primitive booleans is empty or <code>null</code>.</p>
2930         *
2931         * @param array  the array to test
2932         * @return <code>true</code> if the array is empty or <code>null</code>
2933         * @since 2.1
2934         */
2935        public static boolean isEmpty(boolean[] array) {
2936            if (array == null || array.length == 0) {
2937                return true;
2938            }
2939            return false;
2940        }
2941    
2942        /**
2943         * <p>Adds all the elements of the given arrays into a new array.</p>
2944         * <p>The new array contains all of the element of <code>array1</code> followed
2945         * by all of the elements <code>array2</code>. When an array is returned, it is always
2946         * a new array.</p>
2947         *
2948         * <pre>
2949         * ArrayUtils.addAll(null, null)     = null
2950         * ArrayUtils.addAll(array1, null)   = cloned copy of array1
2951         * ArrayUtils.addAll(null, array2)   = cloned copy of array2
2952         * ArrayUtils.addAll([], [])         = []
2953         * ArrayUtils.addAll([null], [null]) = [null, null]
2954         * ArrayUtils.addAll(["a", "b", "c"], ["1", "2", "3"]) = ["a", "b", "c", "1", "2", "3"]
2955         * </pre>
2956         *
2957         * @param array1  the first array whose elements are added to the new array, may be <code>null</code>
2958         * @param array2  the second array whose elements are added to the new array, may be <code>null</code>
2959         * @return The new array, <code>null</code> if <code>null</code> array inputs. 
2960         *      The type of the new array is the type of the first array.
2961         * @since 2.1
2962         */
2963        public static Object[] addAll(Object[] array1, Object[] array2) {
2964            if (array1 == null) {
2965                return clone(array2);
2966            } else if (array2 == null) {
2967                return clone(array1);
2968            }
2969            Object[] joinedArray = (Object[]) Array.newInstance(array1.getClass().getComponentType(),
2970                                                                array1.length + array2.length);
2971            System.arraycopy(array1, 0, joinedArray, 0, array1.length);
2972            System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
2973            return joinedArray;
2974        }
2975    
2976        /**
2977         * <p>Adds all the elements of the given arrays into a new array.</p>
2978         * <p>The new array contains all of the element of <code>array1</code> followed
2979         * by all of the elements <code>array2</code>. When an array is returned, it is always
2980         * a new array.</p>
2981         *
2982         * <pre>
2983         * ArrayUtils.addAll(array1, null)   = cloned copy of array1
2984         * ArrayUtils.addAll(null, array2)   = cloned copy of array2
2985         * ArrayUtils.addAll([], [])         = []
2986         * </pre>
2987         *
2988         * @param array1  the first array whose elements are added to the new array.
2989         * @param array2  the second array whose elements are added to the new array.
2990         * @return The new boolean[] array.
2991         * @since 2.1
2992         */
2993        public static boolean[] addAll(boolean[] array1, boolean[] array2) {
2994            if (array1 == null) {
2995                return clone(array2);
2996            } else if (array2 == null) {
2997                return clone(array1);
2998            }
2999            boolean[] joinedArray = new boolean[array1.length + array2.length];
3000            System.arraycopy(array1, 0, joinedArray, 0, array1.length);
3001            System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
3002            return joinedArray;
3003        }
3004    
3005        /**
3006         * <p>Adds all the elements of the given arrays into a new array.</p>
3007         * <p>The new array contains all of the element of <code>array1</code> followed
3008         * by all of the elements <code>array2</code>. When an array is returned, it is always
3009         * a new array.</p>
3010         *
3011         * <pre>
3012         * ArrayUtils.addAll(array1, null)   = cloned copy of array1
3013         * ArrayUtils.addAll(null, array2)   = cloned copy of array2
3014         * ArrayUtils.addAll([], [])         = []
3015         * </pre>
3016         *
3017         * @param array1  the first array whose elements are added to the new array.
3018         * @param array2  the second array whose elements are added to the new array.
3019         * @return The new char[] array.
3020         * @since 2.1
3021         */
3022        public static char[] addAll(char[] array1, char[] array2) {
3023            if (array1 == null) {
3024                return clone(array2);
3025            } else if (array2 == null) {
3026                return clone(array1);
3027            }
3028            char[] joinedArray = new char[array1.length + array2.length];
3029            System.arraycopy(array1, 0, joinedArray, 0, array1.length);
3030            System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
3031            return joinedArray;
3032        }
3033    
3034        /**
3035         * <p>Adds all the elements of the given arrays into a new array.</p>
3036         * <p>The new array contains all of the element of <code>array1</code> followed
3037         * by all of the elements <code>array2</code>. When an array is returned, it is always
3038         * a new array.</p>
3039         *
3040         * <pre>
3041         * ArrayUtils.addAll(array1, null)   = cloned copy of array1
3042         * ArrayUtils.addAll(null, array2)   = cloned copy of array2
3043         * ArrayUtils.addAll([], [])         = []
3044         * </pre>
3045         *
3046         * @param array1  the first array whose elements are added to the new array.
3047         * @param array2  the second array whose elements are added to the new array.
3048         * @return The new byte[] array.
3049         * @since 2.1
3050         */
3051        public static byte[] addAll(byte[] array1, byte[] array2) {
3052            if (array1 == null) {
3053                return clone(array2);
3054            } else if (array2 == null) {
3055                return clone(array1);
3056            }
3057            byte[] joinedArray = new byte[array1.length + array2.length];
3058            System.arraycopy(array1, 0, joinedArray, 0, array1.length);
3059            System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
3060            return joinedArray;
3061        }
3062    
3063        /**
3064         * <p>Adds all the elements of the given arrays into a new array.</p>
3065         * <p>The new array contains all of the element of <code>array1</code> followed
3066         * by all of the elements <code>array2</code>. When an array is returned, it is always
3067         * a new array.</p>
3068         *
3069         * <pre>
3070         * ArrayUtils.addAll(array1, null)   = cloned copy of array1
3071         * ArrayUtils.addAll(null, array2)   = cloned copy of array2
3072         * ArrayUtils.addAll([], [])         = []
3073         * </pre>
3074         *
3075         * @param array1  the first array whose elements are added to the new array.
3076         * @param array2  the second array whose elements are added to the new array.
3077         * @return The new short[] array.
3078         * @since 2.1
3079         */
3080        public static short[] addAll(short[] array1, short[] array2) {
3081            if (array1 == null) {
3082                return clone(array2);
3083            } else if (array2 == null) {
3084                return clone(array1);
3085            }
3086            short[] joinedArray = new short[array1.length + array2.length];
3087            System.arraycopy(array1, 0, joinedArray, 0, array1.length);
3088            System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
3089            return joinedArray;
3090        }
3091    
3092        /**
3093         * <p>Adds all the elements of the given arrays into a new array.</p>
3094         * <p>The new array contains all of the element of <code>array1</code> followed
3095         * by all of the elements <code>array2</code>. When an array is returned, it is always
3096         * a new array.</p>
3097         *
3098         * <pre>
3099         * ArrayUtils.addAll(array1, null)   = cloned copy of array1
3100         * ArrayUtils.addAll(null, array2)   = cloned copy of array2
3101         * ArrayUtils.addAll([], [])         = []
3102         * </pre>
3103         *
3104         * @param array1  the first array whose elements are added to the new array.
3105         * @param array2  the second array whose elements are added to the new array.
3106         * @return The new int[] array.
3107         * @since 2.1
3108         */
3109        public static int[] addAll(int[] array1, int[] array2) {
3110            if (array1 == null) {
3111                return clone(array2);
3112            } else if (array2 == null) {
3113                return clone(array1);
3114            }
3115            int[] joinedArray = new int[array1.length + array2.length];
3116            System.arraycopy(array1, 0, joinedArray, 0, array1.length);
3117            System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
3118            return joinedArray;
3119        }
3120    
3121        /**
3122         * <p>Adds all the elements of the given arrays into a new array.</p>
3123         * <p>The new array contains all of the element of <code>array1</code> followed
3124         * by all of the elements <code>array2</code>. When an array is returned, it is always
3125         * a new array.</p>
3126         *
3127         * <pre>
3128         * ArrayUtils.addAll(array1, null)   = cloned copy of array1
3129         * ArrayUtils.addAll(null, array2)   = cloned copy of array2
3130         * ArrayUtils.addAll([], [])         = []
3131         * </pre>
3132         *
3133         * @param array1  the first array whose elements are added to the new array.
3134         * @param array2  the second array whose elements are added to the new array.
3135         * @return The new long[] array.
3136         * @since 2.1
3137         */
3138        public static long[] addAll(long[] array1, long[] array2) {
3139            if (array1 == null) {
3140                return clone(array2);
3141            } else if (array2 == null) {
3142                return clone(array1);
3143            }
3144            long[] joinedArray = new long[array1.length + array2.length];
3145            System.arraycopy(array1, 0, joinedArray, 0, array1.length);
3146            System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
3147            return joinedArray;
3148        }
3149    
3150        /**
3151         * <p>Adds all the elements of the given arrays into a new array.</p>
3152         * <p>The new array contains all of the element of <code>array1</code> followed
3153         * by all of the elements <code>array2</code>. When an array is returned, it is always
3154         * a new array.</p>
3155         *
3156         * <pre>
3157         * ArrayUtils.addAll(array1, null)   = cloned copy of array1
3158         * ArrayUtils.addAll(null, array2)   = cloned copy of array2
3159         * ArrayUtils.addAll([], [])         = []
3160         * </pre>
3161         *
3162         * @param array1  the first array whose elements are added to the new array.
3163         * @param array2  the second array whose elements are added to the new array.
3164         * @return The new float[] array.
3165         * @since 2.1
3166         */
3167        public static float[] addAll(float[] array1, float[] array2) {
3168            if (array1 == null) {
3169                return clone(array2);
3170            } else if (array2 == null) {
3171                return clone(array1);
3172            }
3173            float[] joinedArray = new float[array1.length + array2.length];
3174            System.arraycopy(array1, 0, joinedArray, 0, array1.length);
3175            System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
3176            return joinedArray;
3177        }
3178    
3179        /**
3180         * <p>Adds all the elements of the given arrays into a new array.</p>
3181         * <p>The new array contains all of the element of <code>array1</code> followed
3182         * by all of the elements <code>array2</code>. When an array is returned, it is always
3183         * a new array.</p>
3184         *
3185         * <pre>
3186         * ArrayUtils.addAll(array1, null)   = cloned copy of array1
3187         * ArrayUtils.addAll(null, array2)   = cloned copy of array2
3188         * ArrayUtils.addAll([], [])         = []
3189         * </pre>
3190         *
3191         * @param array1  the first array whose elements are added to the new array.
3192         * @param array2  the second array whose elements are added to the new array.
3193         * @return The new double[] array.
3194         * @since 2.1
3195         */
3196        public static double[] addAll(double[] array1, double[] array2) {
3197            if (array1 == null) {
3198                return clone(array2);
3199            } else if (array2 == null) {
3200                return clone(array1);
3201            }
3202            double[] joinedArray = new double[array1.length + array2.length];
3203            System.arraycopy(array1, 0, joinedArray, 0, array1.length);
3204            System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
3205            return joinedArray;
3206        }
3207    
3208        /**
3209         * <p>Copies the given array and adds the given element at the end of the new array.</p>
3210         *
3211         * <p>The new array contains the same elements of the input
3212         * array plus the given element in the last position. The component type of 
3213         * the new array is the same as that of the input array.</p>
3214         *
3215         * <p>If the input array is <code>null</code>, a new one element array is returned
3216         *  whose component type is the same as the element.</p>
3217         * 
3218         * <pre>
3219         * ArrayUtils.add(null, null)      = [null]
3220         * ArrayUtils.add(null, "a")       = ["a"]
3221         * ArrayUtils.add(["a"], null)     = ["a", null]
3222         * ArrayUtils.add(["a"], "b")      = ["a", "b"]
3223         * ArrayUtils.add(["a", "b"], "c") = ["a", "b", "c"]
3224         * </pre>
3225         * 
3226         * @param array  the array to "add" the element to, may be <code>null</code>
3227         * @param element  the object to add
3228         * @return A new array containing the existing elements plus the new element
3229         * @since 2.1
3230         */
3231        public static Object[] add(Object[] array, Object element) {
3232            Class type = array != null ? array.getClass() : (element != null ? element.getClass() : Object.class);
3233            Object[] newArray = (Object[]) copyArrayGrow1(array, type);
3234            newArray[newArray.length - 1] = element;
3235            return newArray;
3236        }
3237        
3238        /**
3239         * <p>Copies the given array and adds the given element at the end of the new array.</p>
3240         *
3241         * <p>The new array contains the same elements of the input
3242         * array plus the given element in the last position. The component type of 
3243         * the new array is the same as that of the input array.</p>
3244         *
3245         * <p>If the input array is <code>null</code>, a new one element array is returned
3246         *  whose component type is the same as the element.</p>
3247         * 
3248         * <pre>
3249         * ArrayUtils.add(null, true)          = [true]
3250         * ArrayUtils.add([true], false)       = [true, false]
3251         * ArrayUtils.add([true, false], true) = [true, false, true]
3252         * </pre>
3253         * 
3254         * @param array  the array to copy and add the element to, may be <code>null</code>
3255         * @param element  the object to add at the last index of the new array
3256         * @return A new array containing the existing elements plus the new element
3257         * @since 2.1
3258         */
3259        public static boolean[] add(boolean[] array, boolean element) {
3260            boolean[] newArray = (boolean[])copyArrayGrow1(array, Boolean.TYPE);
3261            newArray[newArray.length - 1] = element;
3262            return newArray;
3263        }
3264        
3265        /**
3266         * <p>Copies the given array and adds the given element at the end of the new array.</p>
3267         *
3268         * <p>The new array contains the same elements of the input
3269         * array plus the given element in the last position. The component type of 
3270         * the new array is the same as that of the input array.</p>
3271         *
3272         * <p>If the input array is <code>null</code>, a new one element array is returned
3273         *  whose component type is the same as the element.</p>
3274         * 
3275         * <pre>
3276         * ArrayUtils.add(null, 0)   = [0]
3277         * ArrayUtils.add([1], 0)    = [1, 0]
3278         * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
3279         * </pre>
3280         * 
3281         * @param array  the array to copy and add the element to, may be <code>null</code>
3282         * @param element  the object to add at the last index of the new array
3283         * @return A new array containing the existing elements plus the new element
3284         * @since 2.1
3285         */
3286        public static byte[] add(byte[] array, byte element) {
3287            byte[] newArray = (byte[])copyArrayGrow1(array, Byte.TYPE);
3288            newArray[newArray.length - 1] = element;
3289            return newArray;
3290        }
3291        
3292        /**
3293         * <p>Copies the given array and adds the given element at the end of the new array.</p>
3294         *
3295         * <p>The new array contains the same elements of the input
3296         * array plus the given element in the last position. The component type of 
3297         * the new array is the same as that of the input array.</p>
3298         *
3299         * <p>If the input array is <code>null</code>, a new one element array is returned
3300         *  whose component type is the same as the element.</p>
3301         * 
3302         * <pre>
3303         * ArrayUtils.add(null, '0')       = ['0']
3304         * ArrayUtils.add(['1'], '0')      = ['1', '0']
3305         * ArrayUtils.add(['1', '0'], '1') = ['1', '0', '1']
3306         * </pre>
3307         * 
3308         * @param array  the array to copy and add the element to, may be <code>null</code>
3309         * @param element  the object to add at the last index of the new array
3310         * @return A new array containing the existing elements plus the new element
3311         * @since 2.1
3312         */
3313        public static char[] add(char[] array, char element) {
3314            char[] newArray = (char[])copyArrayGrow1(array, Character.TYPE);
3315            newArray[newArray.length - 1] = element;
3316            return newArray;
3317        }
3318        
3319        /**
3320         * <p>Copies the given array and adds the given element at the end of the new array.</p>
3321         *
3322         * <p>The new array contains the same elements of the input
3323         * array plus the given element in the last position. The component type of 
3324         * the new array is the same as that of the input array.</p>
3325         *
3326         * <p>If the input array is <code>null</code>, a new one element array is returned
3327         *  whose component type is the same as the element.</p>
3328         * 
3329         * <pre>
3330         * ArrayUtils.add(null, 0)   = [0]
3331         * ArrayUtils.add([1], 0)    = [1, 0]
3332         * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
3333         * </pre>
3334         * 
3335         * @param array  the array to copy and add the element to, may be <code>null</code>
3336         * @param element  the object to add at the last index of the new array
3337         * @return A new array containing the existing elements plus the new element
3338         * @since 2.1
3339         */
3340        public static double[] add(double[] array, double element) {
3341            double[] newArray = (double[])copyArrayGrow1(array, Double.TYPE);
3342            newArray[newArray.length - 1] = element;
3343            return newArray;
3344        }
3345        
3346        /**
3347         * <p>Copies the given array and adds the given element at the end of the new array.</p>
3348         *
3349         * <p>The new array contains the same elements of the input
3350         * array plus the given element in the last position. The component type of 
3351         * the new array is the same as that of the input array.</p>
3352         *
3353         * <p>If the input array is <code>null</code>, a new one element array is returned
3354         *  whose component type is the same as the element.</p>
3355         * 
3356         * <pre>
3357         * ArrayUtils.add(null, 0)   = [0]
3358         * ArrayUtils.add([1], 0)    = [1, 0]
3359         * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
3360         * </pre>
3361         * 
3362         * @param array  the array to copy and add the element to, may be <code>null</code>
3363         * @param element  the object to add at the last index of the new array
3364         * @return A new array containing the existing elements plus the new element
3365         * @since 2.1
3366         */
3367        public static float[] add(float[] array, float element) {
3368            float[] newArray = (float[])copyArrayGrow1(array, Float.TYPE);
3369            newArray[newArray.length - 1] = element;
3370            return newArray;
3371        }
3372        
3373        /**
3374         * <p>Copies the given array and adds the given element at the end of the new array.</p>
3375         *
3376         * <p>The new array contains the same elements of the input
3377         * array plus the given element in the last position. The component type of 
3378         * the new array is the same as that of the input array.</p>
3379         *
3380         * <p>If the input array is <code>null</code>, a new one element array is returned
3381         *  whose component type is the same as the element.</p>
3382         * 
3383         * <pre>
3384         * ArrayUtils.add(null, 0)   = [0]
3385         * ArrayUtils.add([1], 0)    = [1, 0]
3386         * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
3387         * </pre>
3388         * 
3389         * @param array  the array to copy and add the element to, may be <code>null</code>
3390         * @param element  the object to add at the last index of the new array
3391         * @return A new array containing the existing elements plus the new element
3392         * @since 2.1
3393         */
3394        public static int[] add(int[] array, int element) {
3395            int[] newArray = (int[])copyArrayGrow1(array, Integer.TYPE);
3396            newArray[newArray.length - 1] = element;
3397            return newArray;
3398        }
3399        
3400        /**
3401         * <p>Copies the given array and adds the given element at the end of the new array.</p>
3402         *
3403         * <p>The new array contains the same elements of the input
3404         * array plus the given element in the last position. The component type of 
3405         * the new array is the same as that of the input array.</p>
3406         *
3407         * <p>If the input array is <code>null</code>, a new one element array is returned
3408         *  whose component type is the same as the element.</p>
3409         * 
3410         * <pre>
3411         * ArrayUtils.add(null, 0)   = [0]
3412         * ArrayUtils.add([1], 0)    = [1, 0]
3413         * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
3414         * </pre>
3415         * 
3416         * @param array  the array to copy and add the element to, may be <code>null</code>
3417         * @param element  the object to add at the last index of the new array
3418         * @return A new array containing the existing elements plus the new element
3419         * @since 2.1
3420         */
3421        public static long[] add(long[] array, long element) {
3422            long[] newArray = (long[])copyArrayGrow1(array, Long.TYPE);
3423            newArray[newArray.length - 1] = element;
3424            return newArray;
3425        }
3426        
3427        /**
3428         * <p>Copies the given array and adds the given element at the end of the new array.</p>
3429         *
3430         * <p>The new array contains the same elements of the input
3431         * array plus the given element in the last position. The component type of 
3432         * the new array is the same as that of the input array.</p>
3433         *
3434         * <p>If the input array is <code>null</code>, a new one element array is returned
3435         *  whose component type is the same as the element.</p>
3436         * 
3437         * <pre>
3438         * ArrayUtils.add(null, 0)   = [0]
3439         * ArrayUtils.add([1], 0)    = [1, 0]
3440         * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
3441         * </pre>
3442         * 
3443         * @param array  the array to copy and add the element to, may be <code>null</code>
3444         * @param element  the object to add at the last index of the new array
3445         * @return A new array containing the existing elements plus the new element
3446         * @since 2.1
3447         */
3448        public static short[] add(short[] array, short element) {
3449            short[] newArray = (short[])copyArrayGrow1(array, Short.TYPE);
3450            newArray[newArray.length - 1] = element;
3451            return newArray;
3452        }
3453        
3454        /**
3455         * Returns a copy of the given array of size 1 greater than the argument. 
3456         * The last value of the array is left to the default value.
3457         * 
3458         * @param array The array to copy, must not be <code>null</code>.
3459         * @param newArrayComponentType If <code>array</code> is <code>null</code>, create a 
3460         * size 1 array of this type.
3461         * @return A new copy of the array of size 1 greater than the input.
3462         */    
3463        private static Object copyArrayGrow1(Object array, Class newArrayComponentType) {
3464            if (array != null) {
3465                int arrayLength = Array.getLength(array);
3466                Object newArray = Array.newInstance(array.getClass().getComponentType(), arrayLength + 1);
3467                System.arraycopy(array, 0, newArray, 0, arrayLength);
3468                return newArray;
3469            }
3470            return Array.newInstance(newArrayComponentType, 1);
3471        }
3472        
3473        /**
3474         * <p>Inserts the specified element at the specified position in the array. 
3475         * Shifts the element currently at that position (if any) and any subsequent
3476         * elements to the right (adds one to their indices).</p>
3477         *
3478         * <p>This method returns a new array with the same elements of the input
3479         * array plus the given element on the specified position. The component 
3480         * type of the returned array is always the same as that of the input 
3481         * array.</p>
3482         *
3483         * <p>If the input array is <code>null</code>, a new one element array is returned
3484         *  whose component type is the same as the element.</p>
3485         * 
3486         * <pre>
3487         * ArrayUtils.add(null, 0, null)      = [null]
3488         * ArrayUtils.add(null, 0, "a")       = ["a"]
3489         * ArrayUtils.add(["a"], 1, null)     = ["a", null]
3490         * ArrayUtils.add(["a"], 1, "b")      = ["a", "b"]
3491         * ArrayUtils.add(["a", "b"], 3, "c") = ["a", "b", "c"]
3492         * </pre>
3493         * 
3494         * @param array  the array to add the element to, may be <code>null</code>
3495         * @param index  the position of the new object
3496         * @param element  the object to add
3497         * @return A new array containing the existing elements and the new element
3498         * @throws IndexOutOfBoundsException if the index is out of range 
3499         * (index < 0 || index > array.length).
3500         */
3501        public static Object[] add(Object[] array, int index, Object element) {
3502            Class clss = null;
3503            if (array != null) {
3504                clss = array.getClass().getComponentType();
3505            } else if (element != null) {
3506                clss = element.getClass();
3507            } else {
3508                return new Object[]{null};
3509            }
3510            return (Object[]) add(array, index, element, clss);
3511        }
3512        
3513        /**
3514         * <p>Inserts the specified element at the specified position in the array. 
3515         * Shifts the element currently at that position (if any) and any subsequent
3516         * elements to the right (adds one to their indices).</p>
3517         *
3518         * <p>This method returns a new array with the same elements of the input
3519         * array plus the given element on the specified position. The component 
3520         * type of the returned array is always the same as that of the input 
3521         * array.</p>
3522         *
3523         * <p>If the input array is <code>null</code>, a new one element array is returned
3524         *  whose component type is the same as the element.</p>
3525         * 
3526         * <pre>
3527         * ArrayUtils.add(null, 0, true)          = [true]
3528         * ArrayUtils.add([true], 0, false)       = [false, true]
3529         * ArrayUtils.add([false], 1, true)       = [false, true]
3530         * ArrayUtils.add([true, false], 1, true) = [true, true, false]
3531         * </pre>
3532         * 
3533         * @param array  the array to add the element to, may be <code>null</code>
3534         * @param index  the position of the new object
3535         * @param element  the object to add
3536         * @return A new array containing the existing elements and the new element
3537         * @throws IndexOutOfBoundsException if the index is out of range 
3538         * (index < 0 || index > array.length).
3539         */
3540        public static boolean[] add(boolean[] array, int index, boolean element) {
3541            return (boolean[]) add(array, index, BooleanUtils.toBooleanObject(element), Boolean.TYPE);
3542        }
3543        
3544        /**
3545         * <p>Inserts the specified element at the specified position in the array. 
3546         * Shifts the element currently at that position (if any) and any subsequent
3547         * elements to the right (adds one to their indices).</p>
3548         *
3549         * <p>This method returns a new array with the same elements of the input
3550         * array plus the given element on the specified position. The component 
3551         * type of the returned array is always the same as that of the input 
3552         * array.</p>
3553         *
3554         * <p>If the input array is <code>null</code>, a new one element array is returned
3555         *  whose component type is the same as the element.</p>
3556         * 
3557         * <pre>
3558         * ArrayUtils.add(null, 0, 'a')            = ['a']
3559         * ArrayUtils.add(['a'], 0, 'b')           = ['b', 'a']
3560         * ArrayUtils.add(['a', 'b'], 0, 'c')      = ['c', 'a', 'b']
3561         * ArrayUtils.add(['a', 'b'], 1, 'k')      = ['a', 'k', 'b']
3562         * ArrayUtils.add(['a', 'b', 'c'], 1, 't') = ['a', 't', 'b', 'c']
3563         * </pre>
3564         * 
3565         * @param array  the array to add the element to, may be <code>null</code>
3566         * @param index  the position of the new object
3567         * @param element  the object to add
3568         * @return A new array containing the existing elements and the new element
3569         * @throws IndexOutOfBoundsException if the index is out of range 
3570         * (index < 0 || index > array.length).
3571         */
3572        public static char[] add(char[] array, int index, char element) {
3573            return (char[]) add(array, index, new Character(element), Character.TYPE);
3574        }
3575        
3576        /**
3577         * <p>Inserts the specified element at the specified position in the array. 
3578         * Shifts the element currently at that position (if any) and any subsequent
3579         * elements to the right (adds one to their indices).</p>
3580         *
3581         * <p>This method returns a new array with the same elements of the input
3582         * array plus the given element on the specified position. The component 
3583         * type of the returned array is always the same as that of the input 
3584         * array.</p>
3585         *
3586         * <p>If the input array is <code>null</code>, a new one element array is returned
3587         *  whose component type is the same as the element.</p>
3588         * 
3589         * <pre>
3590         * ArrayUtils.add([1], 0, 2)         = [2, 1]
3591         * ArrayUtils.add([2, 6], 2, 3)      = [2, 6, 3]
3592         * ArrayUtils.add([2, 6], 0, 1)      = [1, 2, 6]
3593         * ArrayUtils.add([2, 6, 3], 2, 1)   = [2, 6, 1, 3]
3594         * </pre>
3595         * 
3596         * @param array  the array to add the element to, may be <code>null</code>
3597         * @param index  the position of the new object
3598         * @param element  the object to add
3599         * @return A new array containing the existing elements and the new element
3600         * @throws IndexOutOfBoundsException if the index is out of range 
3601         * (index < 0 || index > array.length).
3602         */
3603        public static byte[] add(byte[] array, int index, byte element) {
3604            return (byte[]) add(array, index, new Byte(element), Byte.TYPE);
3605        }
3606        
3607        /**
3608         * <p>Inserts the specified element at the specified position in the array. 
3609         * Shifts the element currently at that position (if any) and any subsequent
3610         * elements to the right (adds one to their indices).</p>
3611         *
3612         * <p>This method returns a new array with the same elements of the input
3613         * array plus the given element on the specified position. The component 
3614         * type of the returned array is always the same as that of the input 
3615         * array.</p>
3616         *
3617         * <p>If the input array is <code>null</code>, a new one element array is returned
3618         *  whose component type is the same as the element.</p>
3619         * 
3620         * <pre>
3621         * ArrayUtils.add([1], 0, 2)         = [2, 1]
3622         * ArrayUtils.add([2, 6], 2, 10)     = [2, 6, 10]
3623         * ArrayUtils.add([2, 6], 0, -4)     = [-4, 2, 6]
3624         * ArrayUtils.add([2, 6, 3], 2, 1)   = [2, 6, 1, 3]
3625         * </pre>
3626         * 
3627         * @param array  the array to add the element to, may be <code>null</code>
3628         * @param index  the position of the new object
3629         * @param element  the object to add
3630         * @return A new array containing the existing elements and the new element
3631         * @throws IndexOutOfBoundsException if the index is out of range 
3632         * (index < 0 || index > array.length).
3633         */
3634        public static short[] add(short[] array, int index, short element) {
3635            return (short[]) add(array, index, new Short(element), Short.TYPE);
3636        }
3637        
3638        /**
3639         * <p>Inserts the specified element at the specified position in the array. 
3640         * Shifts the element currently at that position (if any) and any subsequent
3641         * elements to the right (adds one to their indices).</p>
3642         *
3643         * <p>This method returns a new array with the same elements of the input
3644         * array plus the given element on the specified position. The component 
3645         * type of the returned array is always the same as that of the input 
3646         * array.</p>
3647         *
3648         * <p>If the input array is <code>null</code>, a new one element array is returned
3649         *  whose component type is the same as the element.</p>
3650         * 
3651         * <pre>
3652         * ArrayUtils.add([1], 0, 2)         = [2, 1]
3653         * ArrayUtils.add([2, 6], 2, 10)     = [2, 6, 10]
3654         * ArrayUtils.add([2, 6], 0, -4)     = [-4, 2, 6]
3655         * ArrayUtils.add([2, 6, 3], 2, 1)   = [2, 6, 1, 3]
3656         * </pre>
3657         * 
3658         * @param array  the array to add the element to, may be <code>null</code>
3659         * @param index  the position of the new object
3660         * @param element  the object to add
3661         * @return A new array containing the existing elements and the new element
3662         * @throws IndexOutOfBoundsException if the index is out of range 
3663         * (index < 0 || index > array.length).
3664         */
3665        public static int[] add(int[] array, int index, int element) {
3666            return (int[]) add(array, index, new Integer(element), Integer.TYPE);
3667        }
3668        
3669        /**
3670         * <p>Inserts the specified element at the specified position in the array. 
3671         * Shifts the element currently at that position (if any) and any subsequent
3672         * elements to the right (adds one to their indices).</p>
3673         *
3674         * <p>This method returns a new array with the same elements of the input
3675         * array plus the given element on the specified position. The component 
3676         * type of the returned array is always the same as that of the input 
3677         * array.</p>
3678         *
3679         * <p>If the input array is <code>null</code>, a new one element array is returned
3680         *  whose component type is the same as the element.</p>
3681         * 
3682         * <pre>
3683         * ArrayUtils.add([1L], 0, 2L)           = [2L, 1L]
3684         * ArrayUtils.add([2L, 6L], 2, 10L)      = [2L, 6L, 10L]
3685         * ArrayUtils.add([2L, 6L], 0, -4L)      = [-4L, 2L, 6L]
3686         * ArrayUtils.add([2L, 6L, 3L], 2, 1L)   = [2L, 6L, 1L, 3L]
3687         * </pre>
3688         * 
3689         * @param array  the array to add the element to, may be <code>null</code>
3690         * @param index  the position of the new object
3691         * @param element  the object to add
3692         * @return A new array containing the existing elements and the new element
3693         * @throws IndexOutOfBoundsException if the index is out of range 
3694         * (index < 0 || index > array.length).
3695         */
3696        public static long[] add(long[] array, int index, long element) {
3697            return (long[]) add(array, index, new Long(element), Long.TYPE);
3698        }
3699        
3700        /**
3701         * <p>Inserts the specified element at the specified position in the array. 
3702         * Shifts the element currently at that position (if any) and any subsequent
3703         * elements to the right (adds one to their indices).</p>
3704         *
3705         * <p>This method returns a new array with the same elements of the input
3706         * array plus the given element on the specified position. The component 
3707         * type of the returned array is always the same as that of the input 
3708         * array.</p>
3709         *
3710         * <p>If the input array is <code>null</code>, a new one element array is returned
3711         *  whose component type is the same as the element.</p>
3712         * 
3713         * <pre>
3714         * ArrayUtils.add([1.1f], 0, 2.2f)               = [2.2f, 1.1f]
3715         * ArrayUtils.add([2.3f, 6.4f], 2, 10.5f)        = [2.3f, 6.4f, 10.5f]
3716         * ArrayUtils.add([2.6f, 6.7f], 0, -4.8f)        = [-4.8f, 2.6f, 6.7f]
3717         * ArrayUtils.add([2.9f, 6.0f, 0.3f], 2, 1.0f)   = [2.9f, 6.0f, 1.0f, 0.3f]
3718         * </pre>
3719         * 
3720         * @param array  the array to add the element to, may be <code>null</code>
3721         * @param index  the position of the new object
3722         * @param element  the object to add
3723         * @return A new array containing the existing elements and the new element
3724         * @throws IndexOutOfBoundsException if the index is out of range 
3725         * (index < 0 || index > array.length).
3726         */
3727        public static float[] add(float[] array, int index, float element) {
3728            return (float[]) add(array, index, new Float(element), Float.TYPE);
3729        }
3730        
3731        /**
3732         * <p>Inserts the specified element at the specified position in the array. 
3733         * Shifts the element currently at that position (if any) and any subsequent
3734         * elements to the right (adds one to their indices).</p>
3735         *
3736         * <p>This method returns a new array with the same elements of the input
3737         * array plus the given element on the specified position. The component 
3738         * type of the returned array is always the same as that of the input 
3739         * array.</p>
3740         *
3741         * <p>If the input array is <code>null</code>, a new one element array is returned
3742         *  whose component type is the same as the element.</p>
3743         * 
3744         * <pre>
3745         * ArrayUtils.add([1.1], 0, 2.2)              = [2.2, 1.1]
3746         * ArrayUtils.add([2.3, 6.4], 2, 10.5)        = [2.3, 6.4, 10.5]
3747         * ArrayUtils.add([2.6, 6.7], 0, -4.8)        = [-4.8, 2.6, 6.7]
3748         * ArrayUtils.add([2.9, 6.0, 0.3], 2, 1.0)    = [2.9, 6.0, 1.0, 0.3]
3749         * </pre>
3750         * 
3751         * @param array  the array to add the element to, may be <code>null</code>
3752         * @param index  the position of the new object
3753         * @param element  the object to add
3754         * @return A new array containing the existing elements and the new element
3755         * @throws IndexOutOfBoundsException if the index is out of range 
3756         * (index < 0 || index > array.length).
3757         */
3758        public static double[] add(double[] array, int index, double element) {
3759            return (double[]) add(array, index, new Double(element), Double.TYPE);
3760        }
3761        
3762        /**
3763         * Underlying implementation of add(array, index, element) methods. 
3764         * The last parameter is the class, which may not equal element.getClass 
3765         * for primitives.
3766         *
3767         * @param array  the array to add the element to, may be <code>null</code>
3768         * @param index  the position of the new object
3769         * @param element  the object to add
3770         * @param clss the type of the element being added
3771         * @return A new array containing the existing elements and the new element
3772         */
3773        private static Object add(Object array, int index, Object element, Class clss) {
3774            if (array == null) {
3775                if (index != 0) {
3776                    throw new IndexOutOfBoundsException("Index: " + index + ", Length: 0");
3777                }
3778                Object joinedArray = Array.newInstance(clss, 1);
3779                Array.set(joinedArray, 0, element);
3780                return joinedArray;
3781            }
3782            int length = Array.getLength(array);
3783            if (index > length || index < 0) {
3784                throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + length);
3785            }
3786            Object result = Array.newInstance(clss, length + 1);
3787            System.arraycopy(array, 0, result, 0, index);
3788            Array.set(result, index, element);
3789            if (index < length) {
3790                System.arraycopy(array, index, result, index + 1, length - index);
3791            }
3792            return result;
3793        }
3794        
3795        /**
3796         * <p>Removes the element at the specified position from the specified array.
3797         * All subsequent elements are shifted to the left (substracts one from
3798         * their indices).</p>
3799         *
3800         * <p>This method returns a new array with the same elements of the input
3801         * array except the element on the specified position. The component 
3802         * type of the returned array is always the same as that of the input 
3803         * array.</p>
3804         *
3805         * <p>If the input array is <code>null</code>, an IndexOutOfBoundsException
3806         * will be thrown, because in that case no valid index can be specified.</p>
3807         *
3808         * <pre>
3809         * ArrayUtils.remove(["a"], 0)           = []
3810         * ArrayUtils.remove(["a", "b"], 0)      = ["b"]
3811         * ArrayUtils.remove(["a", "b"], 1)      = ["a"]
3812         * ArrayUtils.remove(["a", "b", "c"], 1) = ["a", "c"]
3813         * </pre>
3814         * 
3815         * @param array  the array to remove the element from, may not be <code>null</code>
3816         * @param index  the position of the element to be removed
3817         * @return A new array containing the existing elements except the element
3818         *         at the specified position.
3819         * @throws IndexOutOfBoundsException if the index is out of range 
3820         * (index < 0 || index >= array.length), or if the array is <code>null</code>.
3821         * @since 2.1
3822         */
3823        public static Object[] remove(Object[] array, int index) {
3824            return (Object[]) remove((Object) array, index);
3825        }
3826        
3827        /**
3828         * <p>Removes the first occurrence of the specified element from the
3829         * specified array. All subsequent elements are shifted to the left 
3830         * (substracts one from their indices). If the array doesn't contains
3831         * such an element, no elements are removed from the array.</p>
3832         *
3833         * <p>This method returns a new array with the same elements of the input
3834         * array except the first occurrence of the specified element. The component 
3835         * type of the returned array is always the same as that of the input 
3836         * array.</p>
3837         *
3838         * <pre>
3839         * ArrayUtils.removeElement(null, "a")            = null
3840         * ArrayUtils.removeElement([], "a")              = []
3841         * ArrayUtils.removeElement(["a"], "b")           = ["a"]
3842         * ArrayUtils.removeElement(["a", "b"], "a")      = ["b"]
3843         * ArrayUtils.removeElement(["a", "b", "a"], "a") = ["b", "a"]
3844         * </pre>
3845         * 
3846         * @param array  the array to remove the element from, may be <code>null</code>
3847         * @param element  the element to be removed
3848         * @return A new array containing the existing elements except the first
3849         *         occurrence of the specified element.
3850         * @since 2.1
3851         */
3852        public static Object[] removeElement(Object[] array, Object element) {
3853            int index = indexOf(array, element);
3854            if (index == INDEX_NOT_FOUND) {
3855                return clone(array);
3856            } 
3857            return remove(array, index);
3858        }
3859        
3860        /**
3861         * <p>Removes the element at the specified position from the specified array.
3862         * All subsequent elements are shifted to the left (substracts one from
3863         * their indices).</p>
3864         *
3865         * <p>This method returns a new array with the same elements of the input
3866         * array except the element on the specified position. The component 
3867         * type of the returned array is always the same as that of the input 
3868         * array.</p>
3869         *
3870         * <p>If the input array is <code>null</code>, an IndexOutOfBoundsException
3871         * will be thrown, because in that case no valid index can be specified.</p>
3872         *
3873         * <pre>
3874         * ArrayUtils.remove([true], 0)              = []
3875         * ArrayUtils.remove([true, false], 0)       = [false]
3876         * ArrayUtils.remove([true, false], 1)       = [true]
3877         * ArrayUtils.remove([true, true, false], 1) = [true, false]
3878         * </pre>
3879         * 
3880         * @param array  the array to remove the element from, may not be <code>null</code>
3881         * @param index  the position of the element to be removed
3882         * @return A new array containing the existing elements except the element
3883         *         at the specified position.
3884         * @throws IndexOutOfBoundsException if the index is out of range 
3885         * (index < 0 || index >= array.length), or if the array is <code>null</code>.
3886         * @since 2.1
3887         */
3888        public static boolean[] remove(boolean[] array, int index) {
3889            return (boolean[]) remove((Object) array, index);
3890        }
3891        
3892        /**
3893         * <p>Removes the first occurrence of the specified element from the
3894         * specified array. All subsequent elements are shifted to the left 
3895         * (substracts one from their indices). If the array doesn't contains
3896         * such an element, no elements are removed from the array.</p>
3897         *
3898         * <p>This method returns a new array with the same elements of the input
3899         * array except the first occurrence of the specified element. The component 
3900         * type of the returned array is always the same as that of the input 
3901         * array.</p>
3902         *
3903         * <pre>
3904         * ArrayUtils.removeElement(null, true)                = null
3905         * ArrayUtils.removeElement([], true)                  = []
3906         * ArrayUtils.removeElement([true], false)             = [true]
3907         * ArrayUtils.removeElement([true, false], false)      = [true]
3908         * ArrayUtils.removeElement([true, false, true], true) = [false, true]
3909         * </pre>
3910         * 
3911         * @param array  the array to remove the element from, may be <code>null</code>
3912         * @param element  the element to be removed
3913         * @return A new array containing the existing elements except the first
3914         *         occurrence of the specified element.
3915         * @since 2.1
3916         */
3917        public static boolean[] removeElement(boolean[] array, boolean element) {
3918            int index = indexOf(array, element);
3919            if (index == INDEX_NOT_FOUND) {
3920                return clone(array);
3921            } 
3922            return remove(array, index);
3923        }
3924        
3925        /**
3926         * <p>Removes the element at the specified position from the specified array.
3927         * All subsequent elements are shifted to the left (substracts one from
3928         * their indices).</p>
3929         *
3930         * <p>This method returns a new array with the same elements of the input
3931         * array except the element on the specified position. The component 
3932         * type of the returned array is always the same as that of the input 
3933         * array.</p>
3934         *
3935         * <p>If the input array is <code>null</code>, an IndexOutOfBoundsException
3936         * will be thrown, because in that case no valid index can be specified.</p>
3937         *
3938         * <pre>
3939         * ArrayUtils.remove([1], 0)          = []
3940         * ArrayUtils.remove([1, 0], 0)       = [0]
3941         * ArrayUtils.remove([1, 0], 1)       = [1]
3942         * ArrayUtils.remove([1, 0, 1], 1)    = [1, 1]
3943         * </pre>
3944         * 
3945         * @param array  the array to remove the element from, may not be <code>null</code>
3946         * @param index  the position of the element to be removed
3947         * @return A new array containing the existing elements except the element
3948         *         at the specified position.
3949         * @throws IndexOutOfBoundsException if the index is out of range 
3950         * (index < 0 || index >= array.length), or if the array is <code>null</code>.
3951         * @since 2.1
3952         */
3953        public static byte[] remove(byte[] array, int index) {
3954            return (byte[]) remove((Object) array, index);
3955        }
3956        
3957        /**
3958         * <p>Removes the first occurrence of the specified element from the
3959         * specified array. All subsequent elements are shifted to the left 
3960         * (substracts one from their indices). If the array doesn't contains
3961         * such an element, no elements are removed from the array.</p>
3962         *
3963         * <p>This method returns a new array with the same elements of the input
3964         * array except the first occurrence of the specified element. The component 
3965         * type of the returned array is always the same as that of the input 
3966         * array.</p>
3967         *
3968         * <pre>
3969         * ArrayUtils.removeElement(null, 1)        = null
3970         * ArrayUtils.removeElement([], 1)          = []
3971         * ArrayUtils.removeElement([1], 0)         = [1]
3972         * ArrayUtils.removeElement([1, 0], 0)      = [1]
3973         * ArrayUtils.removeElement([1, 0, 1], 1)   = [0, 1]
3974         * </pre>
3975         * 
3976         * @param array  the array to remove the element from, may be <code>null</code>
3977         * @param element  the element to be removed
3978         * @return A new array containing the existing elements except the first
3979         *         occurrence of the specified element.
3980         * @since 2.1
3981         */
3982        public static byte[] removeElement(byte[] array, byte element) {
3983            int index = indexOf(array, element);
3984            if (index == INDEX_NOT_FOUND) {
3985                return clone(array);
3986            } 
3987            return remove(array, index);
3988        }
3989        
3990        /**
3991         * <p>Removes the element at the specified position from the specified array.
3992         * All subsequent elements are shifted to the left (substracts one from
3993         * their indices).</p>
3994         *
3995         * <p>This method returns a new array with the same elements of the input
3996         * array except the element on the specified position. The component 
3997         * type of the returned array is always the same as that of the input 
3998         * array.</p>
3999         *
4000         * <p>If the input array is <code>null</code>, an IndexOutOfBoundsException
4001         * will be thrown, because in that case no valid index can be specified.</p>
4002         *
4003         * <pre>
4004         * ArrayUtils.remove(['a'], 0)           = []
4005         * ArrayUtils.remove(['a', 'b'], 0)      = ['b']
4006         * ArrayUtils.remove(['a', 'b'], 1)      = ['a']
4007         * ArrayUtils.remove(['a', 'b', 'c'], 1) = ['a', 'c']
4008         * </pre>
4009         * 
4010         * @param array  the array to remove the element from, may not be <code>null</code>
4011         * @param index  the position of the element to be removed
4012         * @return A new array containing the existing elements except the element
4013         *         at the specified position.
4014         * @throws IndexOutOfBoundsException if the index is out of range 
4015         * (index < 0 || index >= array.length), or if the array is <code>null</code>.
4016         * @since 2.1
4017         */
4018        public static char[] remove(char[] array, int index) {
4019            return (char[]) remove((Object) array, index);
4020        }
4021        
4022        /**
4023         * <p>Removes the first occurrence of the specified element from the
4024         * specified array. All subsequent elements are shifted to the left 
4025         * (substracts one from their indices). If the array doesn't contains
4026         * such an element, no elements are removed from the array.</p>
4027         *
4028         * <p>This method returns a new array with the same elements of the input
4029         * array except the first occurrence of the specified element. The component 
4030         * type of the returned array is always the same as that of the input 
4031         * array.</p>
4032         *
4033         * <pre>
4034         * ArrayUtils.removeElement(null, 'a')            = null
4035         * ArrayUtils.removeElement([], 'a')              = []
4036         * ArrayUtils.removeElement(['a'], 'b')           = ['a']
4037         * ArrayUtils.removeElement(['a', 'b'], 'a')      = ['b']
4038         * ArrayUtils.removeElement(['a', 'b', 'a'], 'a') = ['b', 'a']
4039         * </pre>
4040         * 
4041         * @param array  the array to remove the element from, may be <code>null</code>
4042         * @param element  the element to be removed
4043         * @return A new array containing the existing elements except the first
4044         *         occurrence of the specified element.
4045         * @since 2.1
4046         */
4047        public static char[] removeElement(char[] array, char element) {
4048            int index = indexOf(array, element);
4049            if (index == INDEX_NOT_FOUND) {
4050                return clone(array);
4051            } 
4052            return remove(array, index);
4053        }
4054        
4055        /**
4056         * <p>Removes the element at the specified position from the specified array.
4057         * All subsequent elements are shifted to the left (substracts one from
4058         * their indices).</p>
4059         *
4060         * <p>This method returns a new array with the same elements of the input
4061         * array except the element on the specified position. The component 
4062         * type of the returned array is always the same as that of the input 
4063         * array.</p>
4064         *
4065         * <p>If the input array is <code>null</code>, an IndexOutOfBoundsException
4066         * will be thrown, because in that case no valid index can be specified.</p>
4067         *
4068         * <pre>
4069         * ArrayUtils.remove([1.1], 0)           = []
4070         * ArrayUtils.remove([2.5, 6.0], 0)      = [6.0]
4071         * ArrayUtils.remove([2.5, 6.0], 1)      = [2.5]
4072         * ArrayUtils.remove([2.5, 6.0, 3.8], 1) = [2.5, 3.8]
4073         * </pre>
4074         * 
4075         * @param array  the array to remove the element from, may not be <code>null</code>
4076         * @param index  the position of the element to be removed
4077         * @return A new array containing the existing elements except the element
4078         *         at the specified position.
4079         * @throws IndexOutOfBoundsException if the index is out of range 
4080         * (index < 0 || index >= array.length), or if the array is <code>null</code>.
4081         * @since 2.1
4082         */
4083        public static double[] remove(double[] array, int index) {
4084            return (double[]) remove((Object) array, index);
4085        }
4086        
4087        /**
4088         * <p>Removes the first occurrence of the specified element from the
4089         * specified array. All subsequent elements are shifted to the left 
4090         * (substracts one from their indices). If the array doesn't contains
4091         * such an element, no elements are removed from the array.</p>
4092         *
4093         * <p>This method returns a new array with the same elements of the input
4094         * array except the first occurrence of the specified element. The component 
4095         * type of the returned array is always the same as that of the input 
4096         * array.</p>
4097         *
4098         * <pre>
4099         * ArrayUtils.removeElement(null, 1.1)            = null
4100         * ArrayUtils.removeElement([], 1.1)              = []
4101         * ArrayUtils.removeElement([1.1], 1.2)           = [1.1]
4102         * ArrayUtils.removeElement([1.1, 2.3], 1.1)      = [2.3]
4103         * ArrayUtils.removeElement([1.1, 2.3, 1.1], 1.1) = [2.3, 1.1]
4104         * </pre>
4105         * 
4106         * @param array  the array to remove the element from, may be <code>null</code>
4107         * @param element  the element to be removed
4108         * @return A new array containing the existing elements except the first
4109         *         occurrence of the specified element.
4110         * @since 2.1
4111         */
4112        public static double[] removeElement(double[] array, double element) {
4113            int index = indexOf(array, element);
4114            if (index == INDEX_NOT_FOUND) {
4115                return clone(array);
4116            } 
4117            return remove(array, index);
4118        }
4119        
4120        /**
4121         * <p>Removes the element at the specified position from the specified array.
4122         * All subsequent elements are shifted to the left (substracts one from
4123         * their indices).</p>
4124         *
4125         * <p>This method returns a new array with the same elements of the input
4126         * array except the element on the specified position. The component 
4127         * type of the returned array is always the same as that of the input 
4128         * array.</p>
4129         *
4130         * <p>If the input array is <code>null</code>, an IndexOutOfBoundsException
4131         * will be thrown, because in that case no valid index can be specified.</p>
4132         *
4133         * <pre>
4134         * ArrayUtils.remove([1.1], 0)           = []
4135         * ArrayUtils.remove([2.5, 6.0], 0)      = [6.0]
4136         * ArrayUtils.remove([2.5, 6.0], 1)      = [2.5]
4137         * ArrayUtils.remove([2.5, 6.0, 3.8], 1) = [2.5, 3.8]
4138         * </pre>
4139         * 
4140         * @param array  the array to remove the element from, may not be <code>null</code>
4141         * @param index  the position of the element to be removed
4142         * @return A new array containing the existing elements except the element
4143         *         at the specified position.
4144         * @throws IndexOutOfBoundsException if the index is out of range 
4145         * (index < 0 || index >= array.length), or if the array is <code>null</code>.
4146         * @since 2.1
4147         */
4148        public static float[] remove(float[] array, int index) {
4149            return (float[]) remove((Object) array, index);
4150        }
4151        
4152        /**
4153         * <p>Removes the first occurrence of the specified element from the
4154         * specified array. All subsequent elements are shifted to the left 
4155         * (substracts one from their indices). If the array doesn't contains
4156         * such an element, no elements are removed from the array.</p>
4157         *
4158         * <p>This method returns a new array with the same elements of the input
4159         * array except the first occurrence of the specified element. The component 
4160         * type of the returned array is always the same as that of the input 
4161         * array.</p>
4162         *
4163         * <pre>
4164         * ArrayUtils.removeElement(null, 1.1)            = null
4165         * ArrayUtils.removeElement([], 1.1)              = []
4166         * ArrayUtils.removeElement([1.1], 1.2)           = [1.1]
4167         * ArrayUtils.removeElement([1.1, 2.3], 1.1)      = [2.3]
4168         * ArrayUtils.removeElement([1.1, 2.3, 1.1], 1.1) = [2.3, 1.1]
4169         * </pre>
4170         * 
4171         * @param array  the array to remove the element from, may be <code>null</code>
4172         * @param element  the element to be removed
4173         * @return A new array containing the existing elements except the first
4174         *         occurrence of the specified element.
4175         * @since 2.1
4176         */
4177        public static float[] removeElement(float[] array, float element) {
4178            int index = indexOf(array, element);
4179            if (index == INDEX_NOT_FOUND) {
4180                return clone(array);
4181            } 
4182            return remove(array, index);
4183        }
4184        
4185        /**
4186         * <p>Removes the element at the specified position from the specified array.
4187         * All subsequent elements are shifted to the left (substracts one from
4188         * their indices).</p>
4189         *
4190         * <p>This method returns a new array with the same elements of the input
4191         * array except the element on the specified position. The component 
4192         * type of the returned array is always the same as that of the input 
4193         * array.</p>
4194         *
4195         * <p>If the input array is <code>null</code>, an IndexOutOfBoundsException
4196         * will be thrown, because in that case no valid index can be specified.</p>
4197         *
4198         * <pre>
4199         * ArrayUtils.remove([1], 0)         = []
4200         * ArrayUtils.remove([2, 6], 0)      = [6]
4201         * ArrayUtils.remove([2, 6], 1)      = [2]
4202         * ArrayUtils.remove([2, 6, 3], 1)   = [2, 3]
4203         * </pre>
4204         * 
4205         * @param array  the array to remove the element from, may not be <code>null</code>
4206         * @param index  the position of the element to be removed
4207         * @return A new array containing the existing elements except the element
4208         *         at the specified position.
4209         * @throws IndexOutOfBoundsException if the index is out of range 
4210         * (index < 0 || index >= array.length), or if the array is <code>null</code>.
4211         * @since 2.1
4212         */
4213        public static int[] remove(int[] array, int index) {
4214            return (int[]) remove((Object) array, index);
4215        }
4216        
4217        /**
4218         * <p>Removes the first occurrence of the specified element from the
4219         * specified array. All subsequent elements are shifted to the left 
4220         * (substracts one from their indices). If the array doesn't contains
4221         * such an element, no elements are removed from the array.</p>
4222         *
4223         * <p>This method returns a new array with the same elements of the input
4224         * array except the first occurrence of the specified element. The component 
4225         * type of the returned array is always the same as that of the input 
4226         * array.</p>
4227         *
4228         * <pre>
4229         * ArrayUtils.removeElement(null, 1)      = null
4230         * ArrayUtils.removeElement([], 1)        = []
4231         * ArrayUtils.removeElement([1], 2)       = [1]
4232         * ArrayUtils.removeElement([1, 3], 1)    = [3]
4233         * ArrayUtils.removeElement([1, 3, 1], 1) = [3, 1]
4234         * </pre>
4235         * 
4236         * @param array  the array to remove the element from, may be <code>null</code>
4237         * @param element  the element to be removed
4238         * @return A new array containing the existing elements except the first
4239         *         occurrence of the specified element.
4240         * @since 2.1
4241         */
4242        public static int[] removeElement(int[] array, int element) {
4243            int index = indexOf(array, element);
4244            if (index == INDEX_NOT_FOUND) {
4245                return clone(array);
4246            } 
4247            return remove(array, index);
4248        }
4249        
4250        /**
4251         * <p>Removes the element at the specified position from the specified array.
4252         * All subsequent elements are shifted to the left (substracts one from
4253         * their indices).</p>
4254         *
4255         * <p>This method returns a new array with the same elements of the input
4256         * array except the element on the specified position. The component 
4257         * type of the returned array is always the same as that of the input 
4258         * array.</p>
4259         *
4260         * <p>If the input array is <code>null</code>, an IndexOutOfBoundsException
4261         * will be thrown, because in that case no valid index can be specified.</p>
4262         *
4263         * <pre>
4264         * ArrayUtils.remove([1], 0)         = []
4265         * ArrayUtils.remove([2, 6], 0)      = [6]
4266         * ArrayUtils.remove([2, 6], 1)      = [2]
4267         * ArrayUtils.remove([2, 6, 3], 1)   = [2, 3]
4268         * </pre>
4269         * 
4270         * @param array  the array to remove the element from, may not be <code>null</code>
4271         * @param index  the position of the element to be removed
4272         * @return A new array containing the existing elements except the element
4273         *         at the specified position.
4274         * @throws IndexOutOfBoundsException if the index is out of range 
4275         * (index < 0 || index >= array.length), or if the array is <code>null</code>.
4276         * @since 2.1
4277         */
4278        public static long[] remove(long[] array, int index) {
4279            return (long[]) remove((Object) array, index);
4280        }
4281        
4282        /**
4283         * <p>Removes the first occurrence of the specified element from the
4284         * specified array. All subsequent elements are shifted to the left 
4285         * (substracts one from their indices). If the array doesn't contains
4286         * such an element, no elements are removed from the array.</p>
4287         *
4288         * <p>This method returns a new array with the same elements of the input
4289         * array except the first occurrence of the specified element. The component 
4290         * type of the returned array is always the same as that of the input 
4291         * array.</p>
4292         *
4293         * <pre>
4294         * ArrayUtils.removeElement(null, 1)      = null
4295         * ArrayUtils.removeElement([], 1)        = []
4296         * ArrayUtils.removeElement([1], 2)       = [1]
4297         * ArrayUtils.removeElement([1, 3], 1)    = [3]
4298         * ArrayUtils.removeElement([1, 3, 1], 1) = [3, 1]
4299         * </pre>
4300         * 
4301         * @param array  the array to remove the element from, may be <code>null</code>
4302         * @param element  the element to be removed
4303         * @return A new array containing the existing elements except the first
4304         *         occurrence of the specified element.
4305         * @since 2.1
4306         */
4307        public static long[] removeElement(long[] array, long element) {
4308            int index = indexOf(array, element);
4309            if (index == INDEX_NOT_FOUND) {
4310                return clone(array);
4311            } 
4312            return remove(array, index);
4313        }
4314        
4315        /**
4316         * <p>Removes the element at the specified position from the specified array.
4317         * All subsequent elements are shifted to the left (substracts one from
4318         * their indices).</p>
4319         *
4320         * <p>This method returns a new array with the same elements of the input
4321         * array except the element on the specified position. The component 
4322         * type of the returned array is always the same as that of the input 
4323         * array.</p>
4324         *
4325         * <p>If the input array is <code>null</code>, an IndexOutOfBoundsException
4326         * will be thrown, because in that case no valid index can be specified.</p>
4327         *
4328         * <pre>
4329         * ArrayUtils.remove([1], 0)         = []
4330         * ArrayUtils.remove([2, 6], 0)      = [6]
4331         * ArrayUtils.remove([2, 6], 1)      = [2]
4332         * ArrayUtils.remove([2, 6, 3], 1)   = [2, 3]
4333         * </pre>
4334         * 
4335         * @param array  the array to remove the element from, may not be <code>null</code>
4336         * @param index  the position of the element to be removed
4337         * @return A new array containing the existing elements except the element
4338         *         at the specified position.
4339         * @throws IndexOutOfBoundsException if the index is out of range 
4340         * (index < 0 || index >= array.length), or if the array is <code>null</code>.
4341         * @since 2.1
4342         */
4343        public static short[] remove(short[] array, int index) {
4344            return (short[]) remove((Object) array, index);
4345        }
4346        
4347        /**
4348         * <p>Removes the first occurrence of the specified element from the
4349         * specified array. All subsequent elements are shifted to the left 
4350         * (substracts one from their indices). If the array doesn't contains
4351         * such an element, no elements are removed from the array.</p>
4352         *
4353         * <p>This method returns a new array with the same elements of the input
4354         * array except the first occurrence of the specified element. The component 
4355         * type of the returned array is always the same as that of the input 
4356         * array.</p>
4357         *
4358         * <pre>
4359         * ArrayUtils.removeElement(null, 1)      = null
4360         * ArrayUtils.removeElement([], 1)        = []
4361         * ArrayUtils.removeElement([1], 2)       = [1]
4362         * ArrayUtils.removeElement([1, 3], 1)    = [3]
4363         * ArrayUtils.removeElement([1, 3, 1], 1) = [3, 1]
4364         * </pre>
4365         * 
4366         * @param array  the array to remove the element from, may be <code>null</code>
4367         * @param element  the element to be removed
4368         * @return A new array containing the existing elements except the first
4369         *         occurrence of the specified element.
4370         * @since 2.1
4371         */
4372        public static short[] removeElement(short[] array, short element) {
4373            int index = indexOf(array, element);
4374            if (index == INDEX_NOT_FOUND) {
4375                return clone(array);
4376            } 
4377            return remove(array, index);
4378        }
4379        
4380        /**
4381         * <p>Removes the element at the specified position from the specified array.
4382         * All subsequent elements are shifted to the left (substracts one from
4383         * their indices).</p>
4384         *
4385         * <p>This method returns a new array with the same elements of the input
4386         * array except the element on the specified position. The component 
4387         * type of the returned array is always the same as that of the input 
4388         * array.</p>
4389         *
4390         * <p>If the input array is <code>null</code>, an IndexOutOfBoundsException
4391         * will be thrown, because in that case no valid index can be specified.</p>
4392         * 
4393         * @param array  the array to remove the element from, may not be <code>null</code>
4394         * @param index  the position of the element to be removed
4395         * @return A new array containing the existing elements except the element
4396         *         at the specified position.
4397         * @throws IndexOutOfBoundsException if the index is out of range 
4398         * (index < 0 || index >= array.length), or if the array is <code>null</code>.
4399         * @since 2.1
4400         */
4401        private static Object remove(Object array, int index) {
4402            int length = getLength(array);
4403            if (index < 0 || index >= length) {
4404                throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + length);
4405            }
4406            
4407            Object result = Array.newInstance(array.getClass().getComponentType(), length - 1);
4408            System.arraycopy(array, 0, result, 0, index);
4409            if (index < length - 1) {
4410                System.arraycopy(array, index + 1, result, index, length - index - 1);
4411            }
4412            
4413            return result;
4414        }
4415    
4416    }