001    /**
002     * <copyright>
003     *
004     * Copyright (c) 2002-2009 IBM Corporation and others.
005     * All rights reserved.   This program and the accompanying materials
006     * are made available under the terms of the Eclipse Public License v1.0
007     * which accompanies this distribution, and is available at
008     * http://www.eclipse.org/legal/epl-v10.html
009     * 
010     * Contributors: 
011     *   IBM - Initial API and implementation
012     *
013     * </copyright>
014     *
015     * $Id: DelegatingEList.java,v 1.12 2009/01/16 12:55:02 emerks Exp $
016     */
017    package org.eclipse.emf.common.util;
018    
019    
020    import java.io.Serializable;
021    import java.util.Collection;
022    import java.util.Iterator;
023    import java.util.List;
024    import java.util.ListIterator;
025    
026    
027    /**
028     * A highly extensible delegating list implementation.
029     */
030    public abstract class DelegatingEList<E> extends AbstractEList<E> implements Cloneable, Serializable 
031    {
032      private static final long serialVersionUID = 1L;
033    
034      /**
035       * Creates an empty instance.
036       */
037      public DelegatingEList() 
038      {
039        super();
040      }
041    
042      /**
043       * Creates an instance that is a copy of the collection.
044       * @param collection the initial contents of the list.
045       */
046      public DelegatingEList(Collection<? extends E> collection) 
047      {
048        addAll(collection);
049      }
050    
051      /**
052       * Returns the list that acts as the backing store.
053       * @return the list that acts as the backing store.
054       */
055      protected abstract List<E> delegateList();
056    
057      /**
058       * Returns the number of objects in the list.
059       * @return the number of objects in the list.
060       */
061      @Override
062      public int size() 
063      {
064        return delegateSize();
065      }
066    
067      /**
068       * Returns the number of objects in the backing store list.
069       * @return the number of objects in the backing store list.
070       */
071      protected int delegateSize()
072      {
073        return delegateList().size();
074      }
075    
076      /**
077       * Returns whether the list has zero size.
078       * @return whether the list has zero size.
079       */
080      @Override
081      public boolean isEmpty() 
082      {
083        return delegateIsEmpty();
084      }
085    
086      /**
087       * Returns whether the backing store list has zero size.
088       * @return whether the backing store list has zero size.
089       */
090      protected boolean delegateIsEmpty() 
091      {
092        return delegateList().isEmpty();
093      }
094    
095      /**
096       * Returns whether the list contains the object.
097       * @param object the object in question.
098       * @return whether the list contains the object.
099       */
100      @Override
101      public boolean contains(Object object) 
102      {
103        return delegateContains(object);
104      }
105    
106      /**
107       * Returns whether the backing store list contains the object.
108       * @param object the object in question.
109       * @return whether the backing store list contains the object.
110       */
111      protected boolean delegateContains(Object object) 
112      {
113        return delegateList().contains(object);
114      }
115    
116      /**
117       * Returns whether the list contains each object in the collection.
118       * @return whether the list contains each object in the collection.
119       * @see #contains
120       * @see #useEquals
121       */
122      @Override
123      public boolean containsAll(Collection<?> collection) 
124      {
125        return delegateContainsAll(collection);
126      }
127    
128      /**
129       * Returns whether the backing store list contains each object in the collection.
130       * @return whether the backing store list contains each object in the collection.
131       * @see #contains
132       * @see #useEquals
133       */
134      protected boolean delegateContainsAll(Collection<?> collection) 
135      {
136        return delegateList().containsAll(collection);
137      }
138    
139      /**
140       * Returns the position of the first occurrence of the object in the list.
141       * @param object the object in question.
142       * @return the position of the first occurrence of the object in the list.
143       */
144      @Override
145      public int indexOf(Object object) 
146      {
147        return delegateIndexOf(object);
148      }
149    
150      /**
151       * Returns the position of the first occurrence of the object in the backing store list.
152       * @param object the object in question.
153       * @return the position of the first occurrence of the object in the backing store list.
154       */
155      protected int delegateIndexOf(Object object) 
156      {
157        return delegateList().indexOf(object);
158      }
159    
160      /**
161       * Returns the position of the last occurrence of the object in the list.
162       * @param object the object in question.
163       * @return the position of the last occurrence of the object in the list.
164       */
165      @Override
166      public int lastIndexOf(Object object) 
167      {
168        return delegateLastIndexOf(object);
169      }
170    
171      /**
172       * Returns the position of the last occurrence of the object in the backing store list.
173       * @param object the object in question.
174       * @return the position of the last occurrence of the object in the backing store list.
175       */
176      protected int delegateLastIndexOf(Object object) 
177      {
178        return delegateList().lastIndexOf(object);
179      }
180    
181      /**
182       * Returns an array containing all the objects in sequence.
183       * @return an array containing all the objects in sequence.
184       */
185      @Override
186      public Object[] toArray() 
187      {
188        return delegateToArray();
189      }
190    
191      /**
192       * Returns an array containing all the objects in the backing store list in sequence.
193       * @return an array containing all the objects in the backing store list in sequence.
194       */
195      protected Object[] delegateToArray() 
196      {
197        return delegateList().toArray();
198      }
199    
200      /**
201       * Returns an array containing all the objects in sequence.
202       * @param array the array that will be filled and returned, if it's big enough;
203       * otherwise, a suitably large array of the same type will be allocated and used instead.
204       * @return an array containing all the objects in sequence.
205       */
206      @Override
207      public <T> T[] toArray(T[] array) 
208      {
209        return delegateToArray(array);
210      }
211    
212      /**
213       * Returns an array containing all the objects in the backing store list in sequence.
214       * @param array the array that will be filled and returned, if it's big enough;
215       * otherwise, a suitably large array of the same type will be allocated and used instead.
216       * @return an array containing all the objects in sequence.
217       */
218      protected <T> T[] delegateToArray(T[] array) 
219      {
220        return delegateList().toArray(array);
221      }
222    
223      /**
224       * Returns the object at the index.
225       * This implementation delegates to {@link #resolve resolve} 
226       * so that clients may transform the fetched object.
227       * @param index the position in question.
228       * @return the object at the index.
229       * @exception IndexOutOfBoundsException if the index isn't within the size range.
230       * @see #resolve
231       * @see #basicGet
232       */
233      @Override
234      public E get(int index) 
235      {
236        return resolve(index, delegateGet(index));
237      }
238    
239      /**
240       * Returns the object at the index in the backing store list.
241       * @param index the position in question.
242       * @return the object at the index.
243       * @exception IndexOutOfBoundsException if the index isn't within the size range.
244       */
245      protected E delegateGet(int index) 
246      {
247        return delegateList().get(index);
248      }
249    
250      /**
251       * Returns the object at the index without {@link #resolve resolving} it.
252       * @param index the position in question.
253       * @return the object at the index.
254       * @exception IndexOutOfBoundsException if the index isn't within the size range.
255       * @see #resolve
256       * @see #get
257       */
258      @Override
259      protected E basicGet(int index) 
260      {
261        return delegateGet(index);
262      }
263      
264      @Override
265      protected E primitiveGet(int index)
266      {
267        return delegateGet(index);
268      }
269    
270      /**
271       * Sets the object at the index 
272       * and returns the old object at the index;
273       * it does no ranging checking or uniqueness checking.
274       * This implementation delegates to {@link #didSet didSet} and {@link #didChange didChange}.
275       * @param index the position in question.
276       * @param object the object to set.
277       * @return the old object at the index.
278       * @see #set
279       */
280      @Override
281      public E setUnique(int index, E object)
282      {
283        E oldObject = delegateSet(index, validate(index, object));
284        didSet(index, object, oldObject);
285        didChange();
286        return oldObject;
287      }
288    
289      /**
290       * Sets the object at the index in the backing store list
291       * and returns the old object at the index.
292       * @param object the object to set.
293       * @return the old object at the index.
294       */
295      protected E delegateSet(int index, E object)
296      {
297        return delegateList().set(index, object);
298      }
299    
300      /**
301       * Adds the object at the end of the list;
302       * it does no uniqueness checking.
303       * This implementation delegates to {@link #didAdd didAdd} and {@link #didChange didChange}.
304       * after uniqueness checking.
305       * @param object the object to be added.
306       * @see #add(Object)
307       */
308      @Override
309      public void addUnique(E object) 
310      {
311        ++modCount;
312    
313        int size = size();
314        delegateAdd(validate(size, object));
315        didAdd(size, object);
316        didChange();
317      }
318    
319      /**
320       * Adds the object at the end of the backing store list.
321       * @param object the object to be added.
322       */
323      protected void delegateAdd(E object) 
324      {
325        delegateList().add(object);
326      }
327    
328      /**
329       * Adds the object at the given index in the list;
330       * it does no ranging checking or uniqueness checking.
331       * This implementation delegates to {@link #didAdd didAdd} and {@link #didChange didChange}.
332       * @param object the object to be added.
333       * @see #add(int, Object)
334       */
335      @Override
336      public void addUnique(int index, E object) 
337      {
338        ++modCount;
339    
340        delegateAdd(index, validate(index, object));
341        didAdd(index, object);
342        didChange();
343      }
344    
345      /**
346       * Adds the object at the given index in the backing store list.
347       * @param object the object to be added.
348       */
349      protected void delegateAdd(int index, E object) 
350      {
351        delegateList().add(index, object);
352      }
353    
354      /**
355       * Adds each object of the collection to the end of the list;
356       * it does no uniqueness checking.
357       * This implementation delegates to {@link #didAdd didAdd} and {@link #didChange didChange}.
358       * @param collection the collection of objects to be added.
359       * @see #addAll(Collection)
360       */
361      @Override
362      public boolean addAllUnique(Collection<? extends E> collection) 
363      {
364        ++modCount;
365    
366        if (collection.isEmpty())
367        {
368          return false;
369        }
370        else
371        {
372          int i = size();
373          for (E object : collection)
374          {
375            delegateAdd(validate(i, object));
376            didAdd(i, object);
377            didChange();
378            i++;
379          }
380      
381          return true;
382        }
383      }
384    
385      /**
386       * Adds each object of the collection at each successive index in the list 
387       * and returns whether any objects were added;
388       * it does no ranging checking or uniqueness checking.
389       * This implementation delegates to {@link #didAdd didAdd} and {@link #didChange didChange}.
390       * @param index the index at which to add.
391       * @param collection the collection of objects to be added.
392       * @return whether any objects were added.
393       * @see #addAll(int, Collection)
394       */
395      @Override
396      public boolean addAllUnique(int index, Collection<? extends E> collection) 
397      {
398        ++modCount;
399    
400        if (collection.isEmpty())
401        {
402          return false;
403        }
404        else
405        {
406          for (E object : collection)
407          {
408            delegateAdd(index, validate(index, object));
409            didAdd(index, object);
410            didChange();
411            index++;
412          }
413    
414          return true;
415        }
416      }
417    
418      /**
419       * Adds each object from start to end of the array at the index of list 
420       * and returns whether any objects were added;
421       * it does no ranging checking or uniqueness checking.
422       * This implementation delegates to {@link #delegateAdd(Object) delegatedAdd}, {@link #didAdd didAdd}, and {@link #didChange didChange}.
423       * @param objects the objects to be added.
424       * @param start the index of first object to be added.
425       * @param end the index past the last object to be added.
426       * @return whether any objects were added.
427       * @see #addAllUnique(int, Object[], int, int)
428       */
429      @Override
430      public boolean addAllUnique(Object [] objects, int start, int end) 
431      {
432        int growth = end - start;
433    
434        ++modCount;
435        
436        if (growth == 0)
437        {
438          return false;
439        }
440        else
441        {
442          int index = size();
443          for (int i = start; i < end; ++i, ++index)
444          {
445            @SuppressWarnings("unchecked") E object = (E)objects[i];
446            delegateAdd(validate(index, object));
447            didAdd(index, object);
448            didChange();
449          }
450      
451          return true;
452        }
453      }
454    
455      /**
456       * Adds each object from start to end of the array at each successive index in the list 
457       * and returns whether any objects were added;
458       * it does no ranging checking or uniqueness checking.
459       * This implementation delegates to {@link #delegateAdd(int, Object) delegatedAdd}, {@link #didAdd didAdd}, and {@link #didChange didChange}.
460       * @param index the index at which to add.
461       * @param objects the objects to be added.
462       * @param start the index of first object to be added.
463       * @param end the index past the last object to be added.
464       * @return whether any objects were added.
465       * @see #addAllUnique(Object[], int, int)
466       */
467      @Override
468      public boolean addAllUnique(int index, Object [] objects, int start, int end) 
469      {
470        int growth = end - start;
471    
472        ++modCount;
473        
474        if (growth == 0)
475        {
476          return false;
477        }
478        else
479        {
480          for (int i = start; i < end; ++i, ++index)
481          {
482            @SuppressWarnings("unchecked") E object = (E)objects[i];
483            delegateAdd(validate(index, object));
484            didAdd(index, object);
485            didChange();
486          }
487      
488          return true;
489        }
490      }
491    
492      /**
493       * Removes the object from the list and returns whether the object was actually contained by the list.
494       * This implementation uses {@link #indexOf indexOf} to find the object
495       * and delegates to {@link #remove(int) remove(int)} 
496       * in the case that it finds the object.
497       * @param object the object to be removed.
498       * @return whether the object was actually contained by the list.
499       */
500      @Override
501      public boolean remove(Object object) 
502      {
503        int index = indexOf(object);
504        if (index >= 0)
505        {
506          remove(index);
507          return true;
508        }
509        else
510        {
511          return false;
512        }
513      }
514    
515      /**
516       * Removes each object of the collection from the list and returns whether any object was actually contained by the list.
517       * @param collection the collection of objects to be removed.
518       * @return whether any object was actually contained by the list.
519       */
520      @Override
521      public boolean removeAll(Collection<?> collection) 
522      {
523        boolean modified = false;
524        for (ListIterator<?> i = listIterator(); i.hasNext(); )
525        {
526          if (collection.contains(i.next()))
527          {
528            i.remove();
529            modified = true;
530          }
531        }
532    
533        return modified;
534      }
535    
536      /**
537       * Removes the object at the index from the list and returns it.
538       * This implementation delegates to {@link #didRemove didRemove} and {@link #didChange didChange}.
539       * @param index the position of the object to remove.
540       * @return the removed object.
541       * @exception IndexOutOfBoundsException if the index isn't within the size range.
542       */
543      @Override
544      public E remove(int index) 
545      {
546        ++modCount;
547    
548        E oldObject = delegateRemove(index);
549        didRemove(index, oldObject);
550        didChange();
551    
552        return oldObject;
553      }
554    
555      /**
556       * Removes the object at the index from the backing store list and returns it.
557       * @return the removed object.
558       * @exception IndexOutOfBoundsException if the index isn't within the size range.
559       */
560      protected E delegateRemove(int index) 
561      {
562        return delegateList().remove(index);
563      }
564    
565      /**
566       * Removes from the list each object not contained by the collection
567       * and returns whether any object was actually removed.
568       * This delegates to {@link #remove(int) remove(int)} 
569       * in the case that it finds an object that isn't retained.
570       * @param collection the collection of objects to be retained.
571       * @return whether any object was actually removed.
572       */
573      @Override
574      public boolean retainAll(Collection<?> collection) 
575      {
576        boolean modified = false;
577        for (ListIterator<?> i = listIterator(); i.hasNext(); )
578        {
579          if (!collection.contains(i.next()))
580          {
581            i.remove();
582            modified = true;
583          }
584        }
585        return modified;
586      }
587    
588      /**
589       * Clears the list of all objects.
590       */
591      @Override
592      public void clear() 
593      {
594        doClear(size(), delegateToArray());
595      }
596    
597      /**
598       * Does the actual job of clearing all the objects.
599       * @param oldSize the size of the list before it is cleared.
600       * @param oldData old values of the list before it is cleared.
601       */
602      protected void doClear(int oldSize, Object [] oldData) 
603      {
604        ++modCount;
605    
606        delegateClear();
607    
608        didClear(oldSize, oldData);
609        didChange();
610      }
611    
612      /**
613       * Clears the backing store list of all objects.
614       */
615      protected void delegateClear() 
616      {
617        delegateList().clear();
618      }
619    
620      /**
621       * Moves the object at the source index of the list to the target index of the list
622       * and returns the moved object.
623       * This implementation delegates to {@link #didMove didMove} and {@link #didChange didChange}.
624       * @param targetIndex the new position for the object in the list.
625       * @param sourceIndex the old position of the object in the list.
626       * @return the moved object.
627       * @exception IndexOutOfBoundsException if either index isn't within the size range.
628       */
629      @Override
630      public E move(int targetIndex, int sourceIndex)
631      {
632        ++modCount;
633        int size = size();
634        if (targetIndex >= size || targetIndex < 0)
635          throw new IndexOutOfBoundsException("targetIndex=" + targetIndex + ", size=" + size);
636    
637        if (sourceIndex >= size || sourceIndex < 0)
638          throw new IndexOutOfBoundsException("sourceIndex=" + sourceIndex + ", size=" + size);
639    
640        E object;
641        if (targetIndex != sourceIndex)
642        {
643          object = delegateMove(targetIndex, sourceIndex);
644          didMove(targetIndex, object, sourceIndex);
645          didChange();
646        }
647        else
648        {
649          object = delegateGet(sourceIndex);
650        }
651        return object;
652      }
653    
654      /**
655       * Moves the object at the source index in the backing store list by removing it and adding it at the new target index.
656       * @param targetIndex the new position for the object in the list.
657       * @param sourceIndex the old position of the object in the list.
658       * @return the moved object.
659       * @exception IndexOutOfBoundsException if either index isn't within the size range.
660       * @since 2.3
661       */
662      protected E delegateMove(int targetIndex, int sourceIndex)
663      {
664        E result = delegateRemove(sourceIndex);
665        delegateAdd(targetIndex, result);
666        return result;
667      }
668    
669      /**
670       * Returns whether the object is a list with corresponding equal objects.
671       * This implementation uses either <code>equals</code> or <code>"=="</code> depending on {@link #useEquals useEquals}.
672       * @return whether the object is a list with corresponding equal objects.
673       * @see #useEquals
674       */
675      @Override
676      public boolean equals(Object object) 
677      {
678        return delegateEquals(object);
679      }
680    
681      /**
682       * Returns whether the object is a list with corresponding equal objects to those in the backing store list.
683       * @return whether the object is a list with corresponding equal objects.
684       */
685      protected boolean delegateEquals(Object object) 
686      {
687        return delegateList().equals(object);
688      }
689    
690      /**
691       * Returns a hash code computed from each object's hash code.
692       * @return a hash code.
693       */
694      @Override
695      public int hashCode() 
696      {
697        return delegateHashCode();
698      }
699    
700      /**
701       * Returns the hash code of the backing store list.
702       * @return a hash code.
703       */
704      protected int delegateHashCode() 
705      {
706        return delegateList().hashCode();
707      }
708    
709      /**
710       * Returns a string of the form <code>"[object1, object2]"</code>.
711       * @return a string of the form <code>"[object1, object2]"</code>.
712       */
713      @Override
714      public String toString() 
715      {
716        return delegateToString();
717      }
718    
719      /**
720       * Returns a the string form of the backing store list.
721       * @return a the string form of the backing store list.
722       */
723      protected String delegateToString() 
724      {
725        return delegateList().toString();
726      }
727    
728      /**
729       * Returns an iterator over the backing store list.
730       * @return an iterator.
731       */
732      protected Iterator<E> delegateIterator() 
733      {
734        return delegateList().iterator();
735      }
736    
737      /**
738       * An extensible iterator implementation.
739       * @deprecated
740       * @see AbstractEList.EIterator
741       */
742      @Deprecated
743      protected class EIterator<E1> extends AbstractEList<E>.EIterator<E1>
744      {
745        // Pointless extension
746      }
747    
748      /**
749       * An extended read-only iterator that does not {@link DelegatingEList#resolve resolve} objects.
750       * @deprecated
751       * @see AbstractEList.NonResolvingEIterator
752       */
753      @Deprecated
754      protected class NonResolvingEIterator<E1> extends AbstractEList<E>.NonResolvingEIterator<E1>
755      {
756        // Pointless extension
757      }
758    
759      /**
760       * Returns a list iterator over the backing store list.
761       * @return a list iterator.
762       */
763      protected ListIterator<E> delegateListIterator() 
764      {
765        return delegateList().listIterator();
766      }
767    
768      /**
769       * An extensible list iterator implementation.
770       * @deprecated
771       * @see AbstractEList.EListIterator
772       */
773      @Deprecated
774      protected class EListIterator<E1> extends AbstractEList<E>.EListIterator<E1>
775      {
776        /**
777         * Creates an instance.
778         */
779        public EListIterator() 
780        {
781          super();
782        }
783    
784        /**
785         * Creates an instance advanced to the index.
786         * @param index the starting index.
787         */
788        public EListIterator(int index) 
789        {
790          super(index);
791        }
792      }
793    
794      /**
795       * An extended read-only list iterator that does not {@link DelegatingEList#resolve resolve} objects.
796       * @deprecated
797       * @see AbstractEList.NonResolvingEListIterator
798       */
799      @Deprecated
800      protected class NonResolvingEListIterator<E1> extends AbstractEList<E>.NonResolvingEListIterator<E1>
801      {
802        /**
803         * Creates an instance.
804         */
805        public NonResolvingEListIterator()
806        {
807          super();
808        }
809    
810        /**
811         * Creates an instance advanced to the index.
812         * @param index the starting index.
813         */
814        public NonResolvingEListIterator(int index) 
815        {
816          super(index);
817        }
818      }
819    
820      /**
821       * An unmodifiable version of {@link DelegatingEList}.
822       */
823      public static class UnmodifiableEList<E> extends DelegatingEList<E>
824      {
825        private static final long serialVersionUID = 1L;
826    
827        protected List<E> underlyingList;
828    
829        /**
830         * Creates an initialized instance.
831         * @param underlyingList the backing store list.
832         */
833        public UnmodifiableEList(List<E> underlyingList) 
834        {
835          this.underlyingList = underlyingList;
836        }
837    
838        @Override
839        protected List<E> delegateList()
840        {
841          return underlyingList;
842        }
843    
844        /**
845         * Throws an exception.
846         * @exception UnsupportedOperationException always because it's not supported.
847         */
848        @Override
849        public E set(int index, E object) 
850        {
851          throw new UnsupportedOperationException();
852        }
853    
854        /**
855         * Throws an exception.
856         * @exception UnsupportedOperationException always because it's not supported.
857         */
858        @Override
859        public boolean add(E object) 
860        {
861          throw new UnsupportedOperationException();
862        }
863    
864        /**
865         * Throws an exception.
866         * @exception UnsupportedOperationException always because it's not supported.
867         */
868        @Override
869        public void add(int index, E object) 
870        {
871          throw new UnsupportedOperationException();
872        }
873    
874        /**
875         * Throws an exception.
876         * @exception UnsupportedOperationException always because it's not supported.
877         */
878        @Override
879        public boolean addAll(Collection<? extends E> collection) 
880        {
881          throw new UnsupportedOperationException();
882        }
883    
884        /**
885         * Throws an exception.
886         * @exception UnsupportedOperationException always because it's not supported.
887         */
888        @Override
889        public boolean addAll(int index, Collection<? extends E> collection) 
890        {
891          throw new UnsupportedOperationException();
892        }
893    
894        /**
895         * Throws an exception.
896         * @exception UnsupportedOperationException always because it's not supported.
897         */
898        @Override
899        public boolean remove(Object object) 
900        {
901          throw new UnsupportedOperationException();
902        }
903    
904        /**
905         * Throws an exception.
906         * @exception UnsupportedOperationException always because it's not supported.
907         */
908        @Override
909        public E remove(int index) 
910        {
911          throw new UnsupportedOperationException();
912        }
913    
914        /**
915         * Throws an exception.
916         * @exception UnsupportedOperationException always because it's not supported.
917         */
918        @Override
919        public boolean removeAll(Collection<?> collection) 
920        {
921          throw new UnsupportedOperationException();
922        }
923    
924        /**
925         * Throws an exception.
926         * @exception UnsupportedOperationException always because it's not supported.
927         */
928        @Override
929        public boolean retainAll(Collection<?> collection) 
930        {
931          throw new UnsupportedOperationException();
932        }
933    
934        /**
935         * Throws an exception.
936         * @exception UnsupportedOperationException always because it's not supported.
937         */
938        @Override
939        public void clear() 
940        {
941          throw new UnsupportedOperationException();
942        }
943    
944        /**
945         * Throws an exception.
946         * @exception UnsupportedOperationException always because it's not supported.
947         */
948        @Override
949        public void move(int index, E object) 
950        {
951          throw new UnsupportedOperationException();
952        }
953    
954        /**
955         * Throws an exception.
956         * @exception UnsupportedOperationException always because it's not supported.
957         */
958        @Override
959        public E move(int targetIndex, int sourceIndex)
960        {
961          throw new UnsupportedOperationException();
962        }
963    
964        /**
965         * Returns the {@link DelegatingEList#basicIterator basic iterator}.
966         * @return the basic iterator.
967         */
968        @Override
969        public Iterator<E> iterator() 
970        {
971          return basicIterator();
972        }
973    
974        /**
975         * Returns the {@link #basicListIterator() basic list iterator}.
976         * @return the basic list iterator.
977         */
978        @Override
979        public ListIterator<E> listIterator() 
980        {
981          return basicListIterator();
982        }
983      
984        /**
985         * Returns the {@link #basicListIterator(int) basic list iterator} advanced to the index.
986         * @param index the starting index.
987         * @return the basic list iterator.
988         */
989        @Override
990        public ListIterator<E> listIterator(int index) 
991        {
992          return basicListIterator(index);
993        }
994      }
995    
996      /**
997       * Returns an <b>unsafe</b> list that provides a {@link #resolve non-resolving} view of the backing store list.
998       * @return an <b>unsafe</b> list that provides a non-resolving view of the backing store list.
999       */
1000      @Override
1001      protected List<E> basicList()
1002      {
1003        return delegateBasicList();
1004      }
1005    
1006      /**
1007       * Returns an <b>unsafe</b> list that provides a {@link #resolve non-resolving} view of the backing store list.
1008       * @return an <b>unsafe</b> list that provides a non-resolving view of the backing store list.
1009       */
1010      protected List<E> delegateBasicList()
1011      {
1012        return delegateList();
1013      }
1014    }