View Javadoc

1   /*
2    *  Copyright 2001-2010 Stephen Colebourne
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   */
16  package org.joda.primitives.collection.impl;
17  
18  import java.lang.reflect.Array;
19  import java.util.Collection;
20  import java.util.Iterator;
21  
22  import org.joda.primitives.ByteUtils;
23  import org.joda.primitives.collection.ByteCollection;
24  import org.joda.primitives.iterator.ByteIterator;
25  
26  /**
27   * Abstract base class for collections of primitive <code>byte</code> elements.
28   * <p>
29   * This class implements {@link java.util.Collection Collection} allowing
30   * seamless integration with other APIs.
31   * <p>
32   * The <code>iterator</code> and <code>size</code> must be implemented by subclases.
33   * To make the subclass modifiable, the <code>add(byte)</code> and
34   * iterator <code>remove()</code> methods must also be implemented.
35   * Subclasses may override other methods to increase efficiency.
36   *
37   * @author Stephen Colebourne
38   * @author Jason Tiscione
39   * @version CODE GENERATED
40   * @since 1.0
41   */
42  public abstract class AbstractByteCollection
43          extends AbstractPrimitiveCollectable<Byte>
44          implements ByteCollection {
45      // This file is CODE GENERATED. Do not change manually.
46  
47      /**
48       * Constructor.
49       */
50      protected AbstractByteCollection() {
51          super();
52      }
53      
54      // Mandatory operations
55      //-----------------------------------------------------------------------
56      /**
57       * Checks whether this collection contains a specified primitive value.
58       * <p>
59       * This implementation uses <code>byteIterator()</code>.
60       *
61       * @param value  the value to search for
62       * @return <code>true</code> if the value is found
63       */
64      public boolean contains(byte value) {
65          for (ByteIterator it = iterator(); it.hasNext();) {
66              if (it.nextByte() == value) {
67                  return true;
68              }
69          }
70          return false;
71      }
72  
73      /**
74       * Checks if this collection contains all of the values in the specified array.
75       * If the specified array is empty, <code>true</code> is returned.
76       * <p>
77       * This implementation uses <code>contains(byte)</code>.
78       *
79       * @param values  the values to search for, null treated as empty array
80       * @return <code>true</code> if all of the values are found
81       */
82      public boolean containsAll(byte[] values) {
83          if (values != null) {
84              for (int i = 0; i < values.length; i++) {
85                  if (contains(values[i]) == false) {
86                      return false;
87                  }
88              }
89          }
90          return true;
91      }
92  
93      /**
94       * Checks if this collection contains all of the values in the specified collection.
95       * If the specified collection is empty, <code>true</code> is returned.
96       * <p>
97       * This implementation uses <code>contains(byte)</code>.
98       *
99       * @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(ByteCollection values) {
103         if (values != null) {
104             for (ByteIterator it = values.iterator(); it.hasNext(); ) {
105                 if (contains(it.nextByte()) == 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(byte)</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(byte startInclusive, byte endInclusive) {
127         if (startInclusive > endInclusive) {
128             return true;
129         }
130         for (byte 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(byte)</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(byte[] 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(byte)</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(ByteCollection values) {
168         if (values != null) {
169             for (ByteIterator it = values.iterator(); it.hasNext(); ) {
170                 if (contains(it.nextByte())) {
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(byte)</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(byte startInclusive, byte endInclusive) {
192         if (startInclusive > endInclusive) {
193             return false;
194         }
195         for (byte 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 byte[] toByteArray() {
211         if (size() == 0) {
212             return ByteUtils.EMPTY_BYTE_ARRAY;
213         }
214         byte[] result = new byte[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 byte[] toByteArray(byte[] array, int startIndex) {
236         if (startIndex < 0) {
237             throw new IndexOutOfBoundsException("Start index must not be negative: " + startIndex);
238         }
239         byte[] result = null;
240         if (array == null) {
241             // create new
242             result = new byte[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 byte[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 (ByteIterator it = iterator(); it.hasNext();) {
273             it.nextByte();
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(byte 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(byte)</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(byte[] 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(byte)</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(ByteCollection values) {
324         checkAddModifiable();
325         boolean changed = false;
326         if (values != null) {
327             for (ByteIterator it = values.iterator(); it.hasNext(); ) {
328                 changed |= add(it.nextByte());
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(byte)</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(byte startInclusive, byte endInclusive) {
349         checkAddModifiable();
350         if (startInclusive > endInclusive) {
351             return false;
352         }
353         boolean changed = false;
354         for (byte 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(byte value) {
370         checkRemoveModifiable();
371         for (ByteIterator it = iterator(); it.hasNext(); ) {
372             if (it.nextByte() == 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(byte value) {
390         checkRemoveModifiable();
391         boolean changed = false;
392         for (ByteIterator it = iterator(); it.hasNext(); ) {
393             if (it.nextByte() == 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(byte[] values) {
411         checkRemoveModifiable();
412         boolean changed = false;
413         if (values != null) {
414             for (ByteIterator it = iterator(); it.hasNext(); ) {
415                 byte value = it.nextByte();
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(ByteCollection values) {
437         checkRemoveModifiable();
438         boolean changed = false;
439         if (values != null) {
440             for (ByteIterator it = iterator(); it.hasNext(); ) {
441                 if (values.contains(it.nextByte())) {
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(byte startInclusive, byte endInclusive) {
469         checkRemoveModifiable();
470         if (startInclusive > endInclusive) {
471             return false;
472         }
473         boolean changed = false;
474         for (ByteIterator it = iterator(); it.hasNext(); ) {
475             byte value = it.nextByte();
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(byte[] values) {
495         checkRemoveModifiable();
496         boolean changed = false;
497         if (values == null || values.length == 0) {
498             changed = !isEmpty();
499             clear();
500         } else {
501             for (ByteIterator it = iterator(); it.hasNext(); ) {
502                 byte next = it.nextByte();
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(ByteCollection values) {
530         checkRemoveModifiable();
531         boolean changed = false;
532         if (values == null || values.isEmpty()) {
533             changed = !isEmpty();
534             clear();
535         } else {
536             for (ByteIterator it = iterator(); it.hasNext(); ) {
537                 if (values.contains(it.nextByte()) == 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(byte startInclusive, byte endInclusive) {
562         checkRemoveModifiable();
563         boolean changed = false;
564         for (ByteIterator it = iterator(); it.hasNext(); ) {
565             byte value = it.nextByte();
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>Byte</code> value.
578      * <p>
579      * This implementation uses <code>contains(byte)</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(byte[])</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(byte[])</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>Byte</code>.
627      * 
628      * @return an array of <code>Byte</code>
629      */
630     public Object[] toArray() {
631         Object[] result = new Byte[size()];
632         ByteIterator 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>Byte</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<Byte> 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>Byte</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(byte)</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(Byte value) {
678         checkAddModifiable();
679         return add(toPrimitive(value));
680     }
681 
682     /**
683      * Adds a collection of <code>Byte</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(byte[])</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>Byte</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 Byte> coll) {
698         checkAddModifiable();
699         return addAll(toPrimitiveArray(coll));
700     }
701 
702     /**
703      * Removes the first occurrance of the specified <code>Byte</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(byte)</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>Byte</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(byte[])</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>Byte</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(byte[])</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         ByteIterator it = iterator();
777         boolean hasNext = it.hasNext();
778         while (hasNext) {
779             buf.append(it.nextByte());
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, byte[] dest, int destIndex, int size) {
802         ByteIterator it = iterator();
803         for (int i = 0; it.hasNext() && i < size; i++) {
804             dest[destIndex + i] = it.nextByte();
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>byte</code> with an Object wrapper.
859      * 
860      * @param value  the primitive value
861      * @return the Object wrapper
862      */
863     protected Byte toObject(byte value) {
864         return ByteUtils.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 Byte 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 Byte);
877     }
878 
879     /**
880      * Unwraps the <code>Byte</code> to retrieve the primitive <code>byte</code>.
881      * <p>
882      * This implementation only allows non-null Byte 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 byte toPrimitive(Object value) {
890         return ByteUtils.toPrimitive(value);
891     }
892 
893     /**
894      * Unwraps a <code>Collection</code> to retrieve the primitive <code>byte</code>.
895      * <p>
896      * This implementation only allows non-null Byte 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 byte[] toPrimitiveArray(Collection<?> coll) {
904         return ByteUtils.toPrimitiveArray(coll);
905     }
906 
907 }