001    /*
002     *  Copyright 2001-2010 Stephen Colebourne
003     *
004     *  Licensed under the Apache License, Version 2.0 (the "License");
005     *  you may not use this file except in compliance with the License.
006     *  You may obtain a copy of the License at
007     *
008     *      http://www.apache.org/licenses/LICENSE-2.0
009     *
010     *  Unless required by applicable law or agreed to in writing, software
011     *  distributed under the License is distributed on an "AS IS" BASIS,
012     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     *  See the License for the specific language governing permissions and
014     *  limitations under the License.
015     */
016    package org.joda.primitives.collection.impl;
017    
018    import java.lang.reflect.Array;
019    import java.util.Collection;
020    import java.util.Iterator;
021    
022    import org.joda.primitives.LongUtils;
023    import org.joda.primitives.collection.LongCollection;
024    import org.joda.primitives.iterator.LongIterator;
025    
026    /**
027     * Abstract base class for collections of primitive <code>long</code> elements.
028     * <p>
029     * This class implements {@link java.util.Collection Collection} allowing
030     * seamless integration with other APIs.
031     * <p>
032     * The <code>iterator</code> and <code>size</code> must be implemented by subclases.
033     * To make the subclass modifiable, the <code>add(long)</code> and
034     * iterator <code>remove()</code> methods must also be implemented.
035     * Subclasses may override other methods to increase efficiency.
036     *
037     * @author Stephen Colebourne
038     * @author Jason Tiscione
039     * @version CODE GENERATED
040     * @since 1.0
041     */
042    public abstract class AbstractLongCollection
043            extends AbstractPrimitiveCollectable<Long>
044            implements LongCollection {
045        // This file is CODE GENERATED. Do not change manually.
046    
047        /**
048         * Constructor.
049         */
050        protected AbstractLongCollection() {
051            super();
052        }
053        
054        // Mandatory operations
055        //-----------------------------------------------------------------------
056        /**
057         * Checks whether this collection contains a specified primitive value.
058         * <p>
059         * This implementation uses <code>longIterator()</code>.
060         *
061         * @param value  the value to search for
062         * @return <code>true</code> if the value is found
063         */
064        public boolean contains(long value) {
065            for (LongIterator it = iterator(); it.hasNext();) {
066                if (it.nextLong() == value) {
067                    return true;
068                }
069            }
070            return false;
071        }
072    
073        /**
074         * Checks if this collection contains all of the values in the specified array.
075         * If the specified array is empty, <code>true</code> is returned.
076         * <p>
077         * This implementation uses <code>contains(long)</code>.
078         *
079         * @param values  the values to search for, null treated as empty array
080         * @return <code>true</code> if all of the values are found
081         */
082        public boolean containsAll(long[] values) {
083            if (values != null) {
084                for (int i = 0; i < values.length; i++) {
085                    if (contains(values[i]) == false) {
086                        return false;
087                    }
088                }
089            }
090            return true;
091        }
092    
093        /**
094         * Checks if this collection contains all of the values in the specified collection.
095         * If the specified collection is empty, <code>true</code> is returned.
096         * <p>
097         * This implementation uses <code>contains(long)</code>.
098         *
099         * @param values  the values to search for, null treated as empty collection
100         * @return <code>true</code> if all of the values are found
101         */
102        public boolean containsAll(LongCollection values) {
103            if (values != null) {
104                for (LongIterator it = values.iterator(); it.hasNext(); ) {
105                    if (contains(it.nextLong()) == false) {
106                        return false;
107                    }
108                }
109            }
110            return true;
111        }
112    
113        /**
114         * Checks if this collection contain all the values in the specified range.
115         * <p>
116         * The range is defined to be inclusive of the start and end.
117         * If the start is greater than the end then the result is <code>true</code>
118         * as the range is equivalent to an empty collection.
119         * <p>
120         * This implementation uses <code>contains(long)</code>.
121         *
122         * @param startInclusive  the inclusive range start value
123         * @param endInclusive  the inclusive range end value
124         * @return <code>true</code> if the collection contains the entire range
125         */
126        public boolean containsAll(long startInclusive, long endInclusive) {
127            if (startInclusive > endInclusive) {
128                return true;
129            }
130            for (long i = startInclusive; i <= endInclusive; i++) {
131                if (contains(i) == false) {
132                    return false;
133                }
134            }
135            return true;
136        }
137    
138        /**
139         * Checks if this collection contains any of the values in the specified array.
140         * If the specified array is empty, <code>false</code> is returned.
141         * <p>
142         * This implementation uses <code>contains(long)</code>.
143         *
144         * @param values  the values to search for, null treated as empty array
145         * @return <code>true</code> if at least one of the values is found
146         */
147        public boolean containsAny(long[] values) {
148            if (values != null) {
149                for (int i = 0; i < values.length; i++) {
150                    if (contains(values[i])) {
151                        return true;
152                    }
153                }
154            }
155            return false;
156        }
157    
158        /**
159         * Checks if this collection contains any of the values in the specified collection.
160         * If the specified collection is empty, <code>false</code> is returned.
161         * <p>
162         * This implementation uses <code>contains(long)</code>.
163         *
164         * @param values  the values to search for, null treated as empty collection
165         * @return <code>true</code> if at least one of the values is found
166         */
167        public boolean containsAny(LongCollection values) {
168            if (values != null) {
169                for (LongIterator it = values.iterator(); it.hasNext(); ) {
170                    if (contains(it.nextLong())) {
171                        return true;
172                    }
173                }
174            }
175            return false;
176        }
177    
178        /**
179         * Checks if this collection contain some of the values in the specified range.
180         * <p>
181         * The range is defined to be inclusive of the start and end.
182         * If the start is greater than the end then the result is <code>false</code>
183         * as the range is equivalent to an empty collection.
184         * <p>
185         * This implementation uses <code>contains(long)</code>.
186         *
187         * @param startInclusive  the inclusive range start value
188         * @param endInclusive  the inclusive range end value
189         * @return <code>true</code> if the collection contains at least one of the range
190         */
191        public boolean containsAny(long startInclusive, long endInclusive) {
192            if (startInclusive > endInclusive) {
193                return false;
194            }
195            for (long i = startInclusive; i <= endInclusive; i++) {
196                if (contains(i)) {
197                    return true;
198                }
199            }
200            return false;
201        }
202    
203        /**
204         * Gets the elements of this collection as an array.
205         * <p>
206         * This implementation uses <code>arrayCopy</code>.
207         *
208         * @return a new array containing a copy of the elements of this collection
209         */
210        public long[] toLongArray() {
211            if (size() == 0) {
212                return LongUtils.EMPTY_LONG_ARRAY;
213            }
214            long[] result = new long[size()];
215            arrayCopy(0, result, 0, size());
216            return result;
217        }
218    
219        /**
220         * Copies the elements of this collection into an array at a specified position.
221         * Previous values in the array are overwritten.
222         * <p>
223         * If the array specified is null a new array is created.
224         * If the array specified is large enough, it will be modified.
225         * If the array is not large enough, a new array will be created containing the
226         * values from the specified array before the startIndex plus those from this collection.
227         * <p>
228         * This implementation uses <code>arrayCopy</code>.
229         *
230         * @param array  the array to add the elements to, null treated as empty array
231         * @param startIndex  the position in the array to start setting elements
232         * @return the array with the populated collection
233         * @throws IndexOutOfBoundsException if the index is negative
234         */
235        public long[] toLongArray(long[] array, int startIndex) {
236            if (startIndex < 0) {
237                throw new IndexOutOfBoundsException("Start index must not be negative: " + startIndex);
238            }
239            long[] result = null;
240            if (array == null) {
241                // create new
242                result = new long[startIndex + size()];
243                
244            } else if (array.length - startIndex - size() >= 0) {
245                // room to fit data
246                result = array;
247                
248            } else {
249                // expand array
250                result = new long[startIndex + size()];
251                System.arraycopy(array, 0, result, 0, startIndex);
252            }
253            arrayCopy(0, result, startIndex, size());
254            return result;
255        }
256    
257        // Optional operations
258        //-----------------------------------------------------------------------
259        /**
260         * Clears the collection/map of all elements (optional operation).
261         * <p>
262         * The collection/map will have a zero size after this method completes.
263         * This method is optional, throwing an UnsupportedOperationException if the
264         * collection/map cannot be cleared.
265         * <p>
266         * This implementation uses <code>iterator()</code>.
267         *
268         * @throws UnsupportedOperationException if method not supported by this collection
269         */
270        public void clear() {
271            checkRemoveModifiable();
272            for (LongIterator it = iterator(); it.hasNext();) {
273                it.nextLong();
274                it.remove();
275            }
276        }
277    
278        /**
279         * Adds a primitive value to this collection (optional operation).
280         * <p>
281         * This implementation throws UnsupportedOperationException.
282         *
283         * @param value  the value to add to this collection
284         * @return <code>true</code> if this collection was modified by this method call
285         * @throws IllegalArgumentException if value is rejected by this collection
286         * @throws UnsupportedOperationException if not supported by this collection
287         */
288        public boolean add(long value) {
289            throw new UnsupportedOperationException("Collection does not support add");
290        }
291    
292        /**
293         * Adds an array of primitive values to this collection (optional operation).
294         * <p>
295         * This implementation uses <code>add(long)</code>.
296         *
297         * @param values  the values to add to this collection, null treated as empty array
298         * @return <code>true</code> if this collection was modified by this method call
299         * @throws IllegalArgumentException if a value is rejected by this collection
300         * @throws UnsupportedOperationException if not supported by this collection
301         */
302        public boolean addAll(long[] values) {
303            checkAddModifiable();
304            boolean changed = false;
305            if (values != null) {
306                for (int i = 0; i < values.length; i++) {
307                    changed |= add(values[i]);
308                }
309            }
310            return changed;
311        }
312    
313        /**
314         * Adds a collection of primitive values to this collection (optional operation).
315         * <p>
316         * This implementation uses <code>add(long)</code>.
317         *
318         * @param values  the values to add to this collection, null treated as empty collection
319         * @return <code>true</code> if this collection was modified by this method call
320         * @throws IllegalArgumentException if a value is rejected by this collection
321         * @throws UnsupportedOperationException if not supported by this collection
322         */
323        public boolean addAll(LongCollection values) {
324            checkAddModifiable();
325            boolean changed = false;
326            if (values != null) {
327                for (LongIterator it = values.iterator(); it.hasNext(); ) {
328                    changed |= add(it.nextLong());
329                }
330            }
331            return changed;
332        }
333    
334        /**
335         * Adds a range of primitive values to this collection (optional operation).
336         * <p>
337         * The range is defined to be inclusive of the start and end.
338         * If the start is greater than the end then the range is equivalent to an empty collection.
339         * <p>
340         * This implementation uses <code>add(long)</code>.
341         *
342         * @param startInclusive  the inclusive range start value
343         * @param endInclusive  the inclusive range end value
344         * @return <code>true</code> if this collection was modified by this method call
345         * @throws IllegalArgumentException if a value is rejected by this set
346         * @throws UnsupportedOperationException if not supported by this set
347         */
348        public boolean addAll(long startInclusive, long endInclusive) {
349            checkAddModifiable();
350            if (startInclusive > endInclusive) {
351                return false;
352            }
353            boolean changed = false;
354            for (long i = startInclusive; i <= endInclusive; i++) {
355                changed |= add(i);
356            }
357            return false;
358        }
359    
360        /**
361         * Removes the first occurrence of the specified primitive value from this collection
362         * <p>
363         * This implementation uses <code>iterator().remove()</code>.
364         *
365         * @param value  the value to remove
366         * @return <code>true</code> if this collection was modified by this method call
367         * @throws UnsupportedOperationException if not supported by this collection
368         */
369        public boolean removeFirst(long value) {
370            checkRemoveModifiable();
371            for (LongIterator it = iterator(); it.hasNext(); ) {
372                if (it.nextLong() == value) {
373                    it.remove();
374                    return true;
375                }
376            }
377            return false;
378        }
379    
380        /**
381         * Removes all occurrences of the specified primitive value from this collection.
382         * <p>
383         * This implementation uses <code>iterator().remove()</code>.
384         *
385         * @param value  the value to remove
386         * @return <code>true</code> if this collection was modified by this method call
387         * @throws UnsupportedOperationException if not supported by this collection
388         */
389        public boolean removeAll(long value) {
390            checkRemoveModifiable();
391            boolean changed = false;
392            for (LongIterator it = iterator(); it.hasNext(); ) {
393                if (it.nextLong() == value) {
394                    it.remove();
395                    changed = true;
396                }
397            }
398            return changed;
399        }
400    
401        /**
402         * Removes all occurrences from this collection of each primitive in the specified array.
403         * <p>
404         * This implementation uses <code>iterator().remove()</code>.
405         *
406         * @param values  the values to remove from this collection, null treated as empty array
407         * @return <code>true</code> if this list was modified by this method call
408         * @throws UnsupportedOperationException if not supported by this collection
409         */
410        public boolean removeAll(long[] values) {
411            checkRemoveModifiable();
412            boolean changed = false;
413            if (values != null) {
414                for (LongIterator it = iterator(); it.hasNext(); ) {
415                    long value = it.nextLong();
416                    for (int i = 0; i < values.length; i++) {
417                        if (values[i] == value) {
418                            it.remove();
419                            changed = true;
420                        }
421                    }
422                }
423            }
424            return changed;
425        }
426    
427        /**
428         * Removes all occurrences from this collection of each primitive in the specified collection.
429         * <p>
430         * This implementation uses <code>iterator().remove()</code>.
431         *
432         * @param values  the values to remove from this collection, null treated as empty collection
433         * @return <code>true</code> if this list was modified by this method call
434         * @throws UnsupportedOperationException if not supported by this collection
435         */
436        public boolean removeAll(LongCollection values) {
437            checkRemoveModifiable();
438            boolean changed = false;
439            if (values != null) {
440                for (LongIterator it = iterator(); it.hasNext(); ) {
441                    if (values.contains(it.nextLong())) {
442                        it.remove();
443                        changed = true;
444                    }
445                }
446            }
447            return changed;
448        }
449    
450        /**
451         * Removes all occurrences of a range of primitive values from this collection.
452         * <p>
453         * The range is defined to be inclusive of the start and end.
454         * The elements removed are greater than or equal to the start and
455         * less than or equal to the end. Thus if the start is greater than the
456         * end then no elements are removed.
457         * <p>
458         * This method is optional, throwing an UnsupportedOperationException if the
459         * set cannot be changed.
460         * <p>
461         * This implementation uses <code>iterator().remove()</code>.
462         *
463         * @param startInclusive  the inclusive range start value
464         * @param endInclusive  the inclusive range end value
465         * @return <code>true</code> if this collection was modified by this method call
466         * @throws UnsupportedOperationException if not supported by this collection
467         */
468        public boolean removeAll(long startInclusive, long endInclusive) {
469            checkRemoveModifiable();
470            if (startInclusive > endInclusive) {
471                return false;
472            }
473            boolean changed = false;
474            for (LongIterator it = iterator(); it.hasNext(); ) {
475                long value = it.nextLong();
476                if (value >= startInclusive && value <= endInclusive) {
477                    it.remove();
478                    changed = true;
479                }
480            }
481            return changed;
482        }
483    
484        /**
485         * Retains each element of this collection that is present in the specified array
486         * removing all other values.
487         * <p>
488         * This implementation uses <code>iterator().remove()</code>.
489         *
490         * @param values  the values to remove from this collection, null treated as empty array
491         * @return <code>true</code> if this list was modified by this method call
492         * @throws UnsupportedOperationException if not supported by this collection
493         */
494        public boolean retainAll(long[] values) {
495            checkRemoveModifiable();
496            boolean changed = false;
497            if (values == null || values.length == 0) {
498                changed = !isEmpty();
499                clear();
500            } else {
501                for (LongIterator it = iterator(); it.hasNext(); ) {
502                    long next = it.nextLong();
503                    boolean match = false;
504                    for (int i = 0; i < values.length; i++) {
505                        if (values[i] == next) {
506                            match = true;
507                            break;
508                        }
509                    }
510                    if (match == false) {
511                        it.remove();
512                        changed = true;
513                    }
514                }
515            }
516            return changed;
517        }
518    
519        /**
520         * Retains each element of this collection that is present in the specified collection
521         * removing all other values.
522         * <p>
523         * This implementation uses <code>iterator().remove()</code>.
524         *
525         * @param values  the values to retain in this collection, null treated as empty collection
526         * @return <code>true</code> if this collection was modified by this method call
527         * @throws UnsupportedOperationException if not supported by this collection
528         */
529        public boolean retainAll(LongCollection values) {
530            checkRemoveModifiable();
531            boolean changed = false;
532            if (values == null || values.isEmpty()) {
533                changed = !isEmpty();
534                clear();
535            } else {
536                for (LongIterator it = iterator(); it.hasNext(); ) {
537                    if (values.contains(it.nextLong()) == false) {
538                        it.remove();
539                        changed = true;
540                    }
541                }
542            }
543            return changed;
544        }
545    
546        /**
547         * Retains all occurences of a range of primitive values within this collection
548         * removing all values outside the range (optional operation).
549         * <p>
550         * The range is defined to be inclusive of the start and end.
551         * If the start is greater than the end then the range is equivalent to an empty collection.
552         * <p>
553         * This method is optional, throwing an UnsupportedOperationException if the
554         * set cannot be changed.
555         *
556         * @param startInclusive  the inclusive range start value
557         * @param endInclusive  the inclusive range end value
558         * @return <code>true</code> if this collection was modified by this method call
559         * @throws UnsupportedOperationException if not supported by this collection
560         */
561        public boolean retainAll(long startInclusive, long endInclusive) {
562            checkRemoveModifiable();
563            boolean changed = false;
564            for (LongIterator it = iterator(); it.hasNext(); ) {
565                long value = it.nextLong();
566                if (value < startInclusive || value > endInclusive) {
567                    it.remove();
568                    changed = true;
569                }
570            }
571            return changed;
572        }
573    
574        // Collection integration
575        //-----------------------------------------------------------------------
576        /**
577         * Checks whether this collection contains a specified <code>Long</code> value.
578         * <p>
579         * This implementation uses <code>contains(long)</code>.
580         *
581         * @param value  the value to search for
582         * @return <code>true</code> if the value is found
583         */
584        public boolean contains(Object value) {
585            return contains(toPrimitive(value));
586        }
587    
588        /**
589         * Checks if the collection contains all of the primitive values.
590         * <p>
591         * This implementation uses <code>containsAll(long[])</code>.
592         *
593         * @param coll  the collection of values to search for
594         * @return <code>true</code> if all the values are found
595         */
596        public boolean containsAll(Collection<?> coll) {
597            if (coll == this || coll.size() == 0) {
598                return true;
599            }
600            if (size() == 0) {
601                return false;
602            }
603            return containsAll(toPrimitiveArray(coll));
604        }
605    
606        /**
607         * Checks if the collection contains any of the primitive values in the array.
608         * If the specified collection is empty, <code>false</code> is returned.
609         * <p>
610         * This implementation uses <code>containsAny(long[])</code>.
611         *
612         * @param coll  the collection of values to search for
613         * @return <code>true</code> if at least one of the values is found
614         */
615        public boolean containsAny(Collection<?> coll) {
616            if (size() == 0 || coll.size() == 0) {
617                return false;
618            }
619            if (coll == this) {
620                return true;
621            }
622            return containsAny(toPrimitiveArray(coll));
623        }
624    
625        /**
626         * Gets the collection as an array of <code>Long</code>.
627         * 
628         * @return an array of <code>Long</code>
629         */
630        public Object[] toArray() {
631            Object[] result = new Long[size()];
632            LongIterator it = iterator();
633            for (int i = 0; it.hasNext(); i++) {
634                result[i] = it.next();
635            }
636            return result;
637        }
638    
639        /**
640         * Gets the collection as an array, using the array provided.
641         * 
642         * @param array  the array to populate
643         * @return an array of <code>Long</code>
644         */
645        @SuppressWarnings("unchecked")
646        public <T> T[] toArray(T[] array) {
647            int size = size();
648            if (array.length < size) {
649              array = (T[]) Array.newInstance(array.getClass().getComponentType(), size);
650            }
651    
652            Iterator<Long> it = iterator();
653            for (int i = 0; i < size; i++) {
654                array[i] = (T)it.next();
655            }
656    
657            if (array.length > size) {
658                array[size] = null;
659            }
660            
661            return array;
662        }
663    
664        /**
665         * Adds the <code>Long</code> value to this collection (optional operation).
666         * <p>
667         * This method is optional, throwing an UnsupportedOperationException if the
668         * collection cannot be added to.
669         * <p>
670         * This implementation uses <code>add(long)</code>.
671         *
672         * @param value  the value to add to this collection
673         * @return <code>true</code> if this collection was modified by this method call
674         * @throws IllegalArgumentException if value is rejected by this collection
675         * @throws UnsupportedOperationException if not supported by this collection
676         */
677        public boolean add(Long value) {
678            checkAddModifiable();
679            return add(toPrimitive(value));
680        }
681    
682        /**
683         * Adds a collection of <code>Long</code> values to this collection (optional operation).
684         * <p>
685         * This method is optional, throwing an UnsupportedOperationException if the
686         * collection cannot be added to.
687         * <p>
688         * This implementation uses <code>addAll(long[])</code>.
689         *
690         * @param coll  the values to add to this collection
691         * @return <code>true</code> if this list was modified by this method call
692         * @throws IndexOutOfBoundsException if the index is invalid
693         * @throws ClassCastException if any object is not <code>Long</code>
694         * @throws IllegalArgumentException if value is rejected by this collection
695         * @throws UnsupportedOperationException if not supported by this collection
696         */
697        public boolean addAll(Collection<? extends Long> coll) {
698            checkAddModifiable();
699            return addAll(toPrimitiveArray(coll));
700        }
701    
702        /**
703         * Removes the first occurrance of the specified <code>Long</code> value from
704         * this collection (optional operation).
705         * <p>
706         * This method is optional, throwing an UnsupportedOperationException if the
707         * collection cannot be removed from.
708         * <p>
709         * This implementation uses <code>removeFirst(long)</code>.
710         *
711         * @param value  the value to remove
712         * @return <code>true</code> if this collection was modified by this method call
713         * @throws UnsupportedOperationException if not supported by this collection
714         */
715        public boolean remove(Object value) {
716            checkRemoveModifiable();
717            return removeFirst(toPrimitive(value));
718        }
719    
720        /**
721         * Removes each of a collection of <code>Long</code> values from this collection (optional operation).
722         * <p>
723         * This method is optional, throwing an UnsupportedOperationException if the
724         * collection cannot be added to.
725         * <p>
726         * This implementation uses <code>removeAll(long[])</code>.
727         *
728         * @param coll  the values to remove from this collection
729         * @return <code>true</code> if this list was modified by this method call
730         * @throws UnsupportedOperationException if not supported by this collection
731         */
732        public boolean removeAll(Collection<?> coll) {
733            checkRemoveModifiable();
734            if (coll == this) {
735                int size = size();
736                clear();
737                return (size() != size);
738            }
739            return removeAll(toPrimitiveArray(coll));
740        }
741    
742        /**
743         * Retains each of a collection of <code>Long</code> values, removing other
744         * values (optional operation).
745         * <p>
746         * This method is optional, throwing an UnsupportedOperationException if the
747         * collection cannot be added to.
748         * <p>
749         * This implementation uses <code>retainAll(long[])</code>.
750         *
751         * @param coll  the values to retain in this collection
752         * @return <code>true</code> if this list was modified by this method call
753         * @throws UnsupportedOperationException if not supported by this collection
754         */
755        public boolean retainAll(Collection<?> coll) {
756            checkRemoveModifiable();
757            if (coll == this) {
758                return false;
759            }
760            return retainAll(toPrimitiveArray(coll));
761        }
762    
763        // Basics
764        //-----------------------------------------------------------------------
765        /**
766         * Gets a string representing this collection.
767         * <p>
768         * The format used is as per <code>Collection</code>.
769         * 
770         * @return collection as a String
771         */
772        public String toString() {
773            StringBuffer buf = new StringBuffer();
774            buf.append("[");
775    
776            LongIterator it = iterator();
777            boolean hasNext = it.hasNext();
778            while (hasNext) {
779                buf.append(it.nextLong());
780                hasNext = it.hasNext();
781                if (hasNext) {
782                    buf.append(", ");
783                }
784            }
785    
786            buf.append("]");
787            return buf.toString();
788        }
789        
790        // Internals
791        //-----------------------------------------------------------------------
792        /**
793         * Copies data from this collection into the specified array.
794         * This method is pre-validated.
795         * 
796         * @param fromIndex  the index to start from
797         * @param dest  the destination array
798         * @param destIndex  the destination start index
799         * @param size  the number of items to copy
800         */
801        protected void arrayCopy(int fromIndex, long[] dest, int destIndex, int size) {
802            LongIterator it = iterator();
803            for (int i = 0; it.hasNext() && i < size; i++) {
804                dest[destIndex + i] = it.nextLong();
805            }
806        }
807    
808        /**
809         * Are the add methods supported.
810         * <p>
811         * This implementation returns false.
812         *
813         * @return true if supported
814         */
815        protected boolean isAddModifiable() {
816            return false;
817        }
818    
819        /**
820         * Are the remove methods supported.
821         * <p>
822         * This implementation returns false.
823         *
824         * @return true if supported
825         */
826        protected boolean isRemoveModifiable() {
827            return false;
828        }
829    
830        /**
831         * Is the collection modifiable in any way.
832         *
833         * @return true if supported
834         */
835        public boolean isModifiable() {
836            return isAddModifiable() || isRemoveModifiable();
837        }
838    
839        /**
840         * Check whether add is suported and throw an exception.
841         */
842        protected void checkAddModifiable() {
843            if (isAddModifiable() == false) {
844                throw new UnsupportedOperationException("Collection does not support add");
845            }
846        }
847    
848        /**
849         * Check whether remove is suported and throw an exception.
850         */
851        protected void checkRemoveModifiable() {
852            if (isRemoveModifiable() == false) {
853                throw new UnsupportedOperationException("Collection does not support remove");
854            }
855        }
856    
857        /**
858         * Wraps an <code>long</code> with an Object wrapper.
859         * 
860         * @param value  the primitive value
861         * @return the Object wrapper
862         */
863        protected Long toObject(long value) {
864            return LongUtils.toObject(value);
865        }
866    
867        /**
868         * Checks if the object can be converted to a primitive successfully.
869         * <p>
870         * This implementation only allows non-null Long objects.
871         * 
872         * @param value  the Object wrapper
873         * @return true if a primitive value can be successfully extracted
874         */
875        protected boolean isToPrimitivePossible(Object value) {
876            return (value instanceof Long);
877        }
878    
879        /**
880         * Unwraps the <code>Long</code> to retrieve the primitive <code>long</code>.
881         * <p>
882         * This implementation only allows non-null Long objects.
883         * 
884         * @param value  the Object to convert to a primitive
885         * @return the primitive value
886         * @throws NullPointerException if the value is null and this is unacceptable
887         * @throws ClassCastException if the object is of an unsuitable type
888         */
889        protected long toPrimitive(Object value) {
890            return LongUtils.toPrimitive(value);
891        }
892    
893        /**
894         * Unwraps a <code>Collection</code> to retrieve the primitive <code>long</code>.
895         * <p>
896         * This implementation only allows non-null Long objects.
897         * 
898         * @param coll  the Collection to convert to primitives
899         * @return the primitive value
900         * @throws NullPointerException if the value is null and this is unacceptable
901         * @throws ClassCastException if any object is of an unsuitable type
902         */
903        protected long[] toPrimitiveArray(Collection<?> coll) {
904            return LongUtils.toPrimitiveArray(coll);
905        }
906    
907    }