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.list.impl;
017    
018    import java.util.Collection;
019    import java.util.ConcurrentModificationException;
020    import java.util.Iterator;
021    import java.util.List;
022    import java.util.NoSuchElementException;
023    
024    import org.joda.primitives.IntUtils;
025    import org.joda.primitives.collection.impl.AbstractIntCollection;
026    import org.joda.primitives.iterator.IntIterator;
027    import org.joda.primitives.list.IntList;
028    import org.joda.primitives.listiterator.IntListIterator;
029    
030    /**
031     * Abstract base class for lists of primitive <code>int</code> elements.
032     * <p>
033     * This class implements {@link java.util.Collection Collection} allowing
034     * seamless integration with other APIs.
035     * <p>
036     * The <code>get(int)</code> and <code>size()</code> methods must be
037     * implemented by subclases.
038     * To make the subclass modifiable, the <code>add(int, int)</code>,
039     * <code>removeIndex(int)</code> and set(int, int) must also be implemented.
040     * Subclasses may override other methods to increase efficiency.
041     *
042     * @author Stephen Colebourne
043     * @author Rodney Waldhoff
044     * @author Jason Tiscione
045     * @version CODE GENERATED
046     * @since 1.0
047     */
048    public abstract class AbstractIntList extends AbstractIntCollection implements IntList {
049        // This file is CODE GENERATED. Do not change manually.
050    
051        /**
052         * Constructor.
053         */
054        protected AbstractIntList() {
055            super();
056        }
057    
058        // IntList methods
059        //-----------------------------------------------------------------------
060        /**
061         * Gets an iterator over this list.
062         *
063         * @return an iterator over this list, not null
064         */
065        public IntListIterator iterator() {
066            return listIterator(0);
067        }
068    
069        /**
070         * Gets a list iterator over this list.
071         * <p>
072         * This implementation uses <code>intListIterator(int)</code>.
073         *
074         * @return an iterator over this list, not null
075         */
076        public IntListIterator listIterator() {
077            return listIterator(0);
078        }
079    
080        /**
081         * Gets a list iterator over this list from a start index.
082         *
083         * @param index  the index to start from
084         * @return an iterator over this list, not null
085         * @throws IndexOutOfBoundsException if the index is invalid
086         */
087        public IntListIterator listIterator(int index) {
088            checkIndex(index);
089            return new PListIterator(this, index);
090        }
091    
092        /**
093         * Gets the first primitive value.
094         *
095         * @return value at index zero
096         * @throws IndexOutOfBoundsException if the size is zero
097         */
098        public int firstInt() {
099            return getInt(0);
100        }
101    
102        /**
103         * Gets the last primitive value.
104         *
105         * @return value at index <code>size() - 1</code>
106         * @throws IndexOutOfBoundsException if the size is zero
107         */
108        public int lastInt() {
109            return getInt(size() - 1);
110        }
111    
112        /**
113         * Checks whether this collection contains a specified primitive value.
114         * <p>
115         * This implementation uses <code>getInt(int)</code>.
116         *
117         * @param value  the value to search for
118         * @return <code>true</code> if the value is found
119         */
120        public boolean contains(int value) {
121            for (int i = 0, isize = size(); i < isize; i++) {
122                if (getInt(i) == value) {
123                    return true;
124                }
125            }
126            return false;
127        }
128    
129        /**
130         * Gets the first index of the specified primitive value.
131         * <p>
132         * This implementation uses <code>indexof(int, int)</code>.
133         *
134         * @param value  the value to search for
135         * @return the zero-based index, or <code>-1</code> if not found
136         */
137        public int indexOf(int value) {
138            return indexOf(value, 0);
139        }
140    
141        /**
142         * Gets the first index of the specified primitive value from an index.
143         * <p>
144         * This method follows the conventions of <code>String</code> in that a
145         * negative index is treated as zero, and an index greater than the list
146         * size will simply return <code>-1</code>.
147         * <p>
148         * This implementation uses <code>get(int)</code>.
149         *
150         * @param value  the value to search for
151         * @param fromIndexInclusive  the index to start searching from, inclusive
152         * @return the zero-based index, or <code>-1</code> if not found
153         */
154        public int indexOf(int value, int fromIndexInclusive) {
155            if (fromIndexInclusive < 0) {
156                fromIndexInclusive = 0;
157            }
158            for (int i = fromIndexInclusive, isize = size(); i < isize; i++) {
159                if (getInt(i) == value) {
160                    return i;
161                }
162            }
163            return -1;
164        }
165    
166        /**
167         * Gets the last index of the specified primitive value.
168         * <p>
169         * This implementation uses <code>lastIndexof(int, int)</code>.
170         *
171         * @param value  the value to search for
172         * @return the zero-based index, or <code>-1</code> if not found
173         */
174        public int lastIndexOf(int value) {
175            return lastIndexOf(value, size());
176        }
177    
178        /**
179         * Gets the first index of the specified primitive value from an index.
180         * <p>
181         * This method follows the conventions of <code>String</code> in that an
182         * index greater than the list size will start searching at the list size,
183         * and a negative index simply returns <code>-1</code>.
184         * <p>
185         * This implementation uses <code>get(int)</code>.
186         *
187         * @param value  the value to search for
188         * @param fromIndexInclusive  the index to start searching from, inclusive
189         * @return the zero-based index, or <code>-1</code> if not found
190         */
191        public int lastIndexOf(int value, int fromIndexInclusive) {
192            if (fromIndexInclusive >= size()) {
193                fromIndexInclusive = size() - 1;
194            }
195            for (int i = fromIndexInclusive; i >= 0; i--) {
196                if (getInt(i) == value) {
197                    return i;
198                }
199            }
200            return -1;
201        }
202    
203        /**
204         * Gets a range of elements as an array.
205         *
206         * @param fromIndexInclusive  the index to start from, inclusive
207         * @param toIndexExclusive  the index to end at, exclusive
208         * @return a new array containing a copy of the range of elements, not null
209         * @throws IndexOutOfBoundsException if either index is invalid
210         */
211        public int[] toIntArray(int fromIndexInclusive, int toIndexExclusive) {
212            checkRange(fromIndexInclusive, toIndexExclusive);
213            
214            if (fromIndexInclusive == toIndexExclusive) {
215                return IntUtils.EMPTY_INT_ARRAY;
216            }
217            int size = toIndexExclusive - fromIndexInclusive;
218            int[] result = new int[size];
219            arrayCopy(fromIndexInclusive, result, 0, size);
220            return result;
221        }
222    
223        /**
224         * Gets a range view of part of this list.
225         * <p>
226         * This method allows operations to work on a range within the greater list.
227         * Changes made to the either object will affect the other.
228         *
229         * @param fromIndexInclusive  the index to start from, inclusive
230         * @param toIndexExclusive  the index to end at, exclusive
231         * @return a new IntList for the subList, not null
232         * @throws IndexOutOfBoundsException if either index is invalid
233         */
234        public IntList subList(int fromIndexInclusive, int toIndexExclusive) {
235            return null; // TODO
236        }
237    
238        /**
239         * Clears the listof all elements (optional operation).
240         * <p>
241         * This implementation uses <code>removeRange(int, int)</code>.
242         *
243         * @throws UnsupportedOperationException if method not supported by this collection
244         */
245        public void clear() {
246            removeRange(0, size());
247        }
248    
249        /**
250         * Adds a primitive value to this collection (optional operation).
251         * <p>
252         * This implementation uses <code>add(int, int)</code>.
253         *
254         * @param value  the value to add to this collection
255         * @return <code>true</code> if this collection was modified by this method call
256         * @throws IllegalArgumentException if value is rejected by this collection
257         * @throws UnsupportedOperationException if not supported by this collection
258         */
259        public boolean add(int value) {
260            checkAddModifiable();
261            return add(size(), value);
262        }
263    
264        /**
265         * Adds a primitive value to this list at an index (optional operation).
266         * <p>
267         * This implementation throws UnsupportedOperationException.
268         *
269         * @param index  the index to add at
270         * @param value  the value to add to this collection
271         * @return <code>true</code> if this list was modified by this method call
272         * @throws IndexOutOfBoundsException if the index is invalid
273         * @throws IllegalArgumentException if value is rejected by this collection
274         * @throws UnsupportedOperationException if not supported by this collection
275         */
276        public boolean add(int index, int value) {
277            throw new UnsupportedOperationException("List does not support add");
278        }
279    
280        /**
281         * Adds an array of primitive values to this list at an index (optional operation).
282         * <p>
283         * This implementation uses <code>addAll(int, int)</code>.
284         *
285         * @param values  the values to add to this collection, null treated as empty array
286         * @return <code>true</code> if this list was modified by this method call
287         * @throws IndexOutOfBoundsException if the index is invalid
288         * @throws IllegalArgumentException if value is rejected by this collection
289         * @throws UnsupportedOperationException if not supported by this collection
290         */
291        public boolean addAll(int[] values) {
292            checkAddModifiable();
293            return addAll(size(), values);
294        }
295    
296        /**
297         * Adds an array of primitive values to this list at an index (optional operation).
298         * <p>
299         * This method is optional, throwing an UnsupportedOperationException if the
300         * collection cannot be added to.
301         *
302         * @param index  the index to add at
303         * @param values  the values to add to this collection, null treated as empty array
304         * @return <code>true</code> if this list was modified by this method call
305         * @throws IndexOutOfBoundsException if the index is invalid
306         * @throws IllegalArgumentException if value is rejected by this collection
307         * @throws UnsupportedOperationException if not supported by this collection
308         */
309        public boolean addAll(int index, int[] values) {
310            checkAddModifiable();
311            checkIndex(index);
312            boolean changed = false;
313            if (values != null) {
314                for (int i = 0; i < values.length; i++) {
315                    changed |= add(index + i, values[i]);
316                }
317            }
318            return changed;
319        }
320    
321        /**
322         * Removes a primitive value by index from the list (optional operation).
323         * <p>
324         * This implementation throws UnsupportedOperationException.
325         *
326         * @param index  the index to remove from
327         * @return the primitive value previously at this index
328         * @throws IndexOutOfBoundsException if the index is invalid
329         * @throws UnsupportedOperationException if not supported by this collection
330         */
331        public int removeIntAt(int index) {
332            throw new UnsupportedOperationException("List does not support remove");
333        }
334    
335        /**
336         * Removes the first occurrence of a primitive value from the list (optional operation).
337         * <p>
338         * This implementation uses <code>get(int)</code> and <code>removeIntAt(int)</code>.
339         *
340         * @param value  the value to remove
341         * @return the primitive value previously at this index
342         * @throws UnsupportedOperationException if not supported by this collection
343         */
344        public boolean removeInt(int value) {
345            checkRemoveModifiable();
346            for (int i = 0, isize = size(); i < isize; i++) {
347                if (getInt(i) == value) {
348                    removeIntAt(i);
349                    return true;
350                }
351            }
352            return false;
353        }
354    
355        /**
356         * Removes a range of values from the list (optional operation).
357         * <p>
358         * This implementation uses <code>removeIntAt(int)</code>.
359         *
360         * @param fromIndexInclusive  the start of the range to remove, inclusive
361         * @param toIndexExclusive  the end of the range to remove, exclusive
362         * @return <code>true</code> if the collection was modified
363         * @throws IndexOutOfBoundsException if the index is invalid
364         * @throws UnsupportedOperationException if remove is not supported
365         */
366        public boolean removeRange(int fromIndexInclusive, int toIndexExclusive) {
367            checkRemoveModifiable();
368            checkRange(fromIndexInclusive, toIndexExclusive);
369            if (fromIndexInclusive == toIndexExclusive) {
370                return false;
371            }
372            for (int i = size() - 1; i >= 0; i--) {
373                removeIntAt(i);
374            }
375            return true;
376        }
377    
378        /**
379         * Sets the primitive value at a specified index.
380         * <p>
381         * This implementation throws UnsupportedOperationException.
382         *
383         * @param index  the index to set
384         * @param value  the value to store
385         * @return the previous value at the index
386         * @throws IndexOutOfBoundsException if the index is invalid
387         * @throws IllegalArgumentException if value is rejected by this collection
388         * @throws UnsupportedOperationException if not supported by this collection
389         */
390        public int set(int index, int value) {
391            throw new UnsupportedOperationException("List does not support set");
392        }
393    
394        // List methods
395        //-----------------------------------------------------------------------
396        /**
397         * Gets the <code>Integer</code> value at the specified index.
398         *
399         * @param index  the index to get from
400         * @return value at the index
401         * @throws IndexOutOfBoundsException if the index is invalid
402         */
403        public Integer get(int index) {
404            return IntUtils.toObject(getInt(index));
405        }
406    
407        /**
408         * Gets the first <code>Integer</code> value.
409         *
410         * @return value at index zero or null if the size is zero
411         */
412        public Integer first() {
413            if (size() == 0) {
414                return null;
415            }
416            return get(0);
417        }
418    
419        /**
420         * Gets the last <code>Integer</code> value.
421         *
422         * @return value at index <code>size() - 1</code> or null if the size is zero
423         */
424        public Integer last() {
425            if (size() == 0) {
426                return null;
427            }
428            return get(size() - 1);
429        }
430    
431        /**
432         * Gets the first index of the specified <code>Integer</code> value.
433         *
434         * @param value  the value to search for
435         * @return the zero-based index, or <code>-1</code> if not found
436         * @throws NullPointerException if the value if null
437         * @throws ClassCastException if the object is not <code>Integer</code>
438         */
439        public int indexOf(Object value) {
440            return indexOf(IntUtils.toPrimitive(value));
441        }
442    
443        /**
444         * Gets the first index of the specified <code>Integer</code> value from an index.
445         * <p>
446         * This method follows the conventions of <code>String</code> in that a
447         * negative index is treated as zero, and an index greater than the list
448         * size will simply return <code>-1</code>.
449         *
450         * @param value  the value to search for
451         * @param fromIndexInclusive  the index to start searching from, inclusive
452         * @return the zero-based index, or <code>-1</code> if not found
453         * @throws NullPointerException if the value if null
454         * @throws ClassCastException if the object is not <code>Integer</code>
455         */
456        public int indexOf(Object value, int fromIndexInclusive) {
457            return indexOf(IntUtils.toPrimitive(value), fromIndexInclusive);
458        }
459    
460        /**
461         * Gets the last index of the specified <code>Integer</code> value.
462         *
463         * @param value  the value to search for
464         * @return the zero-based index, or <code>-1</code> if not found
465         * @throws NullPointerException if the value if null
466         * @throws ClassCastException if the object is not <code>Integer</code>
467         */
468        public int lastIndexOf(Object value) {
469            return lastIndexOf(IntUtils.toPrimitive(value));
470        }
471    
472        /**
473         * Gets the first index of the specified <code>Integer</code> value from an index.
474         * <p>
475         * This method follows the conventions of <code>String</code> in that an
476         * index greater than the list size will start searching at the list size,
477         * and a negative index simply returns <code>-1</code>.
478         *
479         * @param value  the value to search for
480         * @param fromIndexInclusive  the index to start searching from, inclusive
481         * @return the zero-based index, or <code>-1</code> if not found
482         * @throws NullPointerException if the value if null
483         * @throws ClassCastException if the object is not <code>Integer</code>
484         */
485        public int lastIndexOf(Object value, int fromIndexInclusive) {
486            return lastIndexOf(IntUtils.toPrimitive(value), fromIndexInclusive);
487        }
488    
489        /**
490         * Adds the <code>Integer</code> value to this collection (optional operation).
491         * <p>
492         * This method is optional, throwing an UnsupportedOperationException if the
493         * collection cannot be added to.
494         *
495         * @param value  the value to add to this collection
496         * @return <code>true</code> if this collection was modified by this method call
497         * @throws IllegalArgumentException if value is rejected by this collection
498         * @throws UnsupportedOperationException if not supported by this collection
499         */
500        public boolean add(Integer value) {
501            checkAddModifiable();
502            return add(size(), IntUtils.toPrimitive(value));
503        }
504    
505        /**
506         * Adds the <code>Integer</code> value to this list at an index (optional operation).
507         * <p>
508         * This method is optional, throwing an UnsupportedOperationException if the
509         * collection cannot be added to.
510         *
511         * @param index  the index to add at
512         * @param value  the value to add to this collection
513         * @throws IndexOutOfBoundsException if the index is invalid
514         * @throws ClassCastException if the object is not <code>Integer</code>
515         * @throws IllegalArgumentException if value is rejected by this collection
516         * @throws UnsupportedOperationException if not supported by this collection
517         */
518        public void add(int index, Integer value) {
519            checkAddModifiable();
520            checkIndex(index);
521            add(index, IntUtils.toPrimitive(value));
522        }
523    
524        /**
525         * Adds an array of <code>Integer</code> values to this list at an index (optional operation).
526         * <p>
527         * This method is optional, throwing an UnsupportedOperationException if the
528         * collection cannot be added to.
529         *
530         * @param index  the index to add at
531         * @param coll  the values to add to this collection
532         * @return <code>true</code> if this list was modified by this method call
533         * @throws IndexOutOfBoundsException if the index is invalid
534         * @throws ClassCastException if any object is not <code>Integer</code>
535         * @throws IllegalArgumentException if value is rejected by this collection
536         * @throws UnsupportedOperationException if not supported by this collection
537         */
538        public boolean addAll(int index, Collection<? extends Integer> coll) {
539            checkAddModifiable();
540            checkIndex(index);
541            return addAll(index, IntUtils.toPrimitiveArray(coll));
542        }
543    
544        /**
545         * Removes a primitive value by index from the list (optional operation).
546         * <p>
547         * This implementation uses <code>removeIntAt(int)</code>.
548         *
549         * @deprecated This method should only be used when working with List and
550         *  not when working with IntList - use <code>removeIntAt(int)</code>
551         * @param index  the index to remove from
552         * @return the primitive value previously at this index
553         * @throws IndexOutOfBoundsException if the index is invalid
554         * @throws UnsupportedOperationException if not supported by this collection
555         */
556        public Integer remove(int index) {
557            checkRemoveModifiable();
558            return IntUtils.toObject(removeIntAt(index));
559        }
560    
561        /**
562         * Sets the <code>Integer</code> value at a specified index.
563         * <p>
564         * This implementation uses <code>set(int, int)</code>.
565         *
566         * @param index  the index to set
567         * @param value  the value to store
568         * @return the previous value at the index
569         * @throws IndexOutOfBoundsException if the index is invalid
570         * @throws IllegalArgumentException if value is rejected by this collection
571         * @throws UnsupportedOperationException if not supported by this collection
572         */
573        public Integer set(int index, Integer value) {
574            checkSetModifiable();
575            checkIndexExists(index);
576            return IntUtils.toObject(set(index, IntUtils.toPrimitive(value)));
577        }
578    
579        //-----------------------------------------------------------------------
580        /**
581         * Compares this list to another as per the contract of <code>List</code>.
582         *
583         * @param obj  the object to compare to
584         * @return <code>true</code> if the lists are equal
585         */
586        public boolean equals(Object obj) {
587            if (obj == this) {
588                return true;
589            }
590            if (obj instanceof IntList) {
591                IntList other = (IntList) obj;
592                if (size() != other.size()) {
593                    return false;
594                }
595                IntIterator it1 = listIterator();
596                IntIterator it2 = other.listIterator();
597                while (it1.hasNext() && it2.hasNext()) {
598                    if (it1.nextInt() != it2.nextInt()) {
599                        return false;
600                    }
601                }
602                return true;
603            } else if (obj instanceof List<?>) {
604                List<?> other = (List<?>) obj;
605                if (size() != other.size()) {
606                    return false;
607                }
608                IntIterator it1 = listIterator();
609                Iterator<?> it2 = other.listIterator();
610                while (it1.hasNext() && it2.hasNext()) {
611                    Object next = it2.next();
612                    if (isToPrimitivePossible(next) == false) {
613                        return false;
614                    }
615                    if (it1.nextInt() != toPrimitive(next)) {
616                        return false;
617                    }
618                }
619                return true;
620            } else {
621                return false;
622            }
623        }
624    
625        /**
626         * Gets the hashCode of this list as per the contract of <code>List</code>.
627         *
628         * @return the hash code for this list
629         */
630        public int hashCode() {
631            int hashCode = 1;
632            Iterator<Integer> it = iterator();
633            while (it.hasNext()) {
634                Object obj = it.next();
635                hashCode = 31 * hashCode + (obj == null ? 0 : obj.hashCode());
636            }
637            return hashCode;
638        }
639    
640        //-----------------------------------------------------------------------
641        /**
642         * Copies data from this collection into the specified array.
643         * This method is pre-validated.
644         * 
645         * @param fromIndex  the index to start from
646         * @param dest  the destination array
647         * @param destIndex  the destination start index
648         * @param size  the number of items to copy
649         */
650        protected void arrayCopy(int fromIndex, int[] dest, int destIndex, int size) {
651            for (int i = 0; i < size; i++) {
652                dest[i + destIndex] = getInt(i + fromIndex);
653            }
654        }
655    
656        /**
657         * Are the set methods supported.
658         * <p>
659         * This implementation returns false.
660         *
661         * @return true if supported
662         */
663        protected boolean isSetModifiable() {
664            return false;
665        }
666    
667        /**
668         * Is the collection modifiable in any way.
669         *
670         * @return true if supported
671         */
672        public boolean isModifiable() {
673            return isAddModifiable() || isRemoveModifiable() || isSetModifiable();
674        }
675    
676        /**
677         * Check whether add is suported and throw an exception.
678         */
679        protected void checkSetModifiable() {
680            if (isSetModifiable() == false) {
681                throw new UnsupportedOperationException("Collection does not support set");
682            }
683        }
684    
685        /**
686         * Checks whether an index is valid or not.
687         * 
688         * @param index  the index to check
689         * @throws IndexOutOfBoundsException if either index is invalid
690         */
691        protected void checkIndexExists(int index) {
692            if (index < 0) {
693                throw new ArrayIndexOutOfBoundsException(
694                    "Index less than zero: " + index + " < 0");
695            }
696            if (index >= size()) {
697                throw new ArrayIndexOutOfBoundsException(
698                    "Index greater than/equal to size(): " + index + " >= " + size());
699            }
700        }
701    
702        /**
703         * Checks whether an index is valid or not.
704         * 
705         * @param index  the index to check
706         * @throws IndexOutOfBoundsException if either index is invalid
707         */
708        protected void checkIndex(int index) {
709            if (index < 0) {
710                throw new ArrayIndexOutOfBoundsException(
711                    "Index less than zero: " + index + " < 0");
712            }
713            if (index > size()) {
714                throw new ArrayIndexOutOfBoundsException(
715                    "Index greater than size(): " + index + " > " + size());
716            }
717        }
718    
719        /**
720         * Checks whether a range is valid or not.
721         * 
722         * @param fromIndexInclusive  the index to start from, inclusive
723         * @param toIndexExclusive  the index to end at, exclusive
724         * @throws IndexOutOfBoundsException if either index is invalid
725         */
726        protected void checkRange(int fromIndexInclusive, int toIndexExclusive) {
727            if (fromIndexInclusive < 0) {
728                throw new ArrayIndexOutOfBoundsException(
729                    "From index less than zero: " + fromIndexInclusive + " < 0");
730            }
731            if (toIndexExclusive > size()) {
732                throw new ArrayIndexOutOfBoundsException(
733                    "To index greater than size(): " + toIndexExclusive + " > " + size());
734            }
735            if (fromIndexInclusive > toIndexExclusive) {
736                throw new ArrayIndexOutOfBoundsException(
737                    "To index greater than from index: " + fromIndexInclusive + " > " + toIndexExclusive);
738            }
739        }
740    
741        //-----------------------------------------------------------------------
742        /**
743         * List iterator.
744         */
745        protected static class PListIterator implements IntListIterator {
746    
747            private final AbstractIntList iList;
748            private final int iStart;
749            private int iCursor = 0;
750            private int iLastIndex = -1;
751            
752            protected PListIterator(AbstractIntList list, int start) {
753                super();
754                this.iList = list;
755                this.iStart = start;
756                this.iCursor = start;
757            }
758    
759            //-----------------------------------------------------------------------
760            public boolean hasNext() {
761                return (iCursor < iList.size());
762            }
763    
764            public int nextInt() {
765                if (hasNext() == false) {
766                    throw new NoSuchElementException("No more elements available");
767                }
768                iLastIndex = iCursor;
769                return iList.getInt(iCursor++);
770            }
771    
772            public Integer next() {
773                return iList.toObject(nextInt());
774            }
775    
776            public int nextIndex() {
777                return iCursor;
778            }
779    
780            //-----------------------------------------------------------------------
781            public boolean hasPrevious() {
782                return (iCursor > 0);
783            }
784    
785            public int previousInt() {
786                if (hasPrevious() == false) {
787                    throw new NoSuchElementException("No more elements available");
788                }
789                iLastIndex = --iCursor;
790                return iList.getInt(iCursor);
791            }
792    
793            public Integer previous() {
794                return iList.toObject(previousInt());
795            }
796    
797            public int previousIndex() {
798                return iCursor - 1;
799            }
800    
801            //-----------------------------------------------------------------------
802            public void remove() {
803                iList.checkRemoveModifiable();
804                if (iLastIndex == -1) {
805                    throw new IllegalStateException("Element cannot be removed");
806                }
807                iList.removeIntAt(iLastIndex);
808                iCursor = iLastIndex;
809                iLastIndex = -1;
810            }
811    
812            public void add(int value) {
813                iList.checkAddModifiable();
814                try {
815                    iList.add(iCursor++, value);
816                    iLastIndex = -1;
817                } catch (IndexOutOfBoundsException ex) {
818                    throw new ConcurrentModificationException("The underlying list was modified");
819                }
820            }
821    
822            public void add(Integer obj) {
823                iList.checkAddModifiable();
824                add(iList.toPrimitive(obj));
825            }
826            
827            public void set(int value) {
828                iList.checkSetModifiable();
829                if (iLastIndex == -1) {
830                    throw new IllegalStateException("Element cannot be set");
831                }
832                try {
833                    iList.set(iLastIndex, value);
834                } catch (IndexOutOfBoundsException ex) {
835                    throw new ConcurrentModificationException("The underlying list was modified");
836                }
837            }
838    
839            public void set(Integer obj) {
840                iList.checkSetModifiable();
841                set(iList.toPrimitive(obj));
842            }
843    
844            //-----------------------------------------------------------------------
845            public boolean isModifiable() {
846                return iList.isModifiable();
847            }
848    
849            public boolean isResettable() {
850                return true;
851            }
852    
853            public void reset() {
854                iCursor = iStart;
855            }
856    
857        }
858    
859    }
860