KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > emf > ecore > util > BasicFeatureMap


1 /**
2  * <copyright>
3  *
4  * Copyright (c) 2003-2004 IBM Corporation and others.
5  * All rights reserved. This program and the accompanying materials
6  * are made available under the terms of the Eclipse Public License v1.0
7  * which accompanies this distribution, and is available at
8  * http://www.eclipse.org/legal/epl-v10.html
9  *
10  * Contributors:
11  * IBM - Initial API and implementation
12  *
13  * </copyright>
14  *
15  * $Id: BasicFeatureMap.java,v 1.18 2005/06/12 13:29:22 emerks Exp $
16  */

17 package org.eclipse.emf.ecore.util;
18
19
20 import java.util.Collection JavaDoc;
21 import java.util.Collections JavaDoc;
22 import java.util.Iterator JavaDoc;
23 import java.util.List JavaDoc;
24 import java.util.ListIterator JavaDoc;
25
26 import org.eclipse.emf.common.notify.Notification;
27 import org.eclipse.emf.common.notify.NotificationChain;
28 import org.eclipse.emf.common.notify.impl.NotificationImpl;
29 import org.eclipse.emf.common.util.BasicEList;
30 import org.eclipse.emf.common.util.EList;
31 import org.eclipse.emf.ecore.EObject;
32 import org.eclipse.emf.ecore.EReference;
33 import org.eclipse.emf.ecore.EStructuralFeature;
34 import org.eclipse.emf.ecore.InternalEObject;
35 import org.eclipse.emf.ecore.impl.ENotificationImpl;
36
37
38
39 public class BasicFeatureMap extends EDataTypeEList implements FeatureMap.Internal
40 {
41   protected final FeatureMapUtil.Validator featureMapValidator;
42
43   public BasicFeatureMap(InternalEObject owner, int featureID)
44   {
45     super(Entry.class, owner, featureID);
46
47     featureMapValidator = FeatureMapUtil.getValidator(owner.eClass(), getEStructuralFeature());
48   }
49
50   protected Object JavaDoc validate(int index, Object JavaDoc object)
51   {
52     Object JavaDoc result = super.validate(index, object);
53     EStructuralFeature eStructuralFeature = ((Entry)object).getEStructuralFeature();
54     if (!eStructuralFeature.isChangeable() || !featureMapValidator.isValid(eStructuralFeature))
55     {
56       throw
57         new RuntimeException JavaDoc
58           ("Invalid entry feature '" + eStructuralFeature.getEContainingClass().getName() + "." + eStructuralFeature.getName() + "'");
59     }
60     return result;
61   }
62
63   protected FeatureMap.Entry createEntry(EStructuralFeature eStructuralFeature, Object JavaDoc value)
64   {
65     return FeatureMapUtil.createEntry(eStructuralFeature, value);
66   }
67
68   protected NotificationImpl createNotification
69     (int eventType, EStructuralFeature feature, Object JavaDoc oldObject, Object JavaDoc newObject, int index, boolean wasSet)
70   {
71     return new FeatureMapUtil.FeatureENotificationImpl(owner, eventType, feature, oldObject, newObject, index, wasSet);
72   }
73
74   protected boolean isMany(EStructuralFeature feature)
75   {
76     return FeatureMapUtil.isMany(owner, feature);
77   }
78
79   protected boolean hasInverse()
80   {
81     return true;
82   }
83
84   protected boolean hasShadow()
85   {
86     return true;
87   }
88
89   protected int entryIndex(EStructuralFeature feature, int index)
90   {
91     FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
92     int count = 0;
93     int result = size;
94     Entry [] entries = (Entry[])data;
95     for (int i = 0; i < size; ++i)
96     {
97       Entry entry = entries[i];
98       if (validator.isValid(entry.getEStructuralFeature()))
99       {
100         if (index == count)
101         {
102           return i;
103         }
104         ++count;
105         result = i + 1;
106       }
107     }
108
109     if (index == count)
110     {
111       return result;
112     }
113     else
114     {
115       throw new IndexOutOfBoundsException JavaDoc("index=" + index + ", size=" + count);
116     }
117   }
118
119   protected boolean isResolveProxies(EStructuralFeature feature)
120   {
121     return feature instanceof EReference && ((EReference)feature).isResolveProxies();
122   }
123
124   public Object JavaDoc resolveProxy(EStructuralFeature feature, int entryIndex, int index, Object JavaDoc object)
125   {
126     EObject resolved = resolveProxy((EObject)object);
127     if (resolved != object)
128     {
129       Object JavaDoc oldObject = data[entryIndex];
130       Entry entry = createEntry(feature, resolved);
131       assign(entryIndex, validate(entryIndex, entry));
132       didSet(entryIndex, entry, oldObject);
133
134       if (isNotificationRequired())
135       {
136         NotificationImpl notifications =
137           createNotification
138             (Notification.RESOLVE,
139              entry.getEStructuralFeature(),
140              object,
141              resolved,
142              index,
143              false);
144
145         notifications.add(createNotification(Notification.RESOLVE, oldObject, entry, index, false));
146         notifications.dispatch();
147       }
148
149       return resolved;
150     }
151
152     return object;
153   }
154
155   protected EObject resolveProxy(EObject eObject)
156   {
157     return owner.eResolveProxy((InternalEObject)eObject);
158   }
159
160   public int getModCount()
161   {
162     return modCount;
163   }
164
165   public EStructuralFeature getEStructuralFeature(int index)
166   {
167     return ((Entry)get(index)).getEStructuralFeature();
168   }
169
170   public Object JavaDoc getValue(int index)
171   {
172     return ((Entry)get(index)).getValue();
173   }
174
175   public Object JavaDoc setValue(int index, Object JavaDoc value)
176   {
177     return ((Entry)set(index, createEntry(getEStructuralFeature(index), value))).getValue();
178   }
179
180   public NotificationChain shadowAdd(Object JavaDoc object, NotificationChain notifications)
181   {
182     if (isNotificationRequired())
183     {
184       Entry entry = (Entry)object;
185       EStructuralFeature feature = entry.getEStructuralFeature();
186       Object JavaDoc value = entry.getValue();
187       // EATM must fix isSet bits.
188
NotificationImpl notification =
189         feature.isMany() ?
190           createNotification
191             (Notification.ADD,
192              feature,
193              null,
194              value,
195              indexOf(feature, value),
196              true) :
197           createNotification
198             (Notification.SET,
199              feature,
200              feature.getDefaultValue(),
201              value,
202              Notification.NO_INDEX,
203              true);
204   
205       if (notifications != null)
206       {
207         notifications.add(notification);
208       }
209       else
210       {
211         notifications = notification;
212       }
213     }
214     return notifications;
215   }
216
217   public NotificationChain inverseAdd(Object JavaDoc object, NotificationChain notifications)
218   {
219     Entry entry = (Entry)object;
220     EStructuralFeature feature = entry.getEStructuralFeature();
221     if (feature instanceof EReference)
222     {
223       EReference eReference = (EReference)feature;
224       EReference eOpposite = eReference.getEOpposite();
225       if (eOpposite != null)
226       {
227         InternalEObject internalEObject = (InternalEObject)entry.getValue();
228
229         if (internalEObject != null)
230         {
231           notifications =
232             internalEObject.eInverseAdd
233               (owner,
234                internalEObject.eClass().getFeatureID(eOpposite),
235                null,
236                notifications);
237         }
238       }
239       else if (eReference.isContainment())
240       {
241         InternalEObject internalEObject = (InternalEObject)entry.getValue();
242         if (internalEObject != null)
243         {
244           int containmentFeatureID = owner.eClass().getFeatureID(eReference);
245           notifications =
246             internalEObject.eInverseAdd
247               (owner,
248                InternalEObject.EOPPOSITE_FEATURE_BASE - (containmentFeatureID == -1 ? featureID : containmentFeatureID),
249                null,
250                notifications);
251         }
252       }
253     }
254
255     return notifications;
256   }
257
258   public NotificationChain shadowRemove(Object JavaDoc object, NotificationChain notifications)
259   {
260     if (isNotificationRequired())
261     {
262       Entry entry = (Entry)object;
263       EStructuralFeature feature = entry.getEStructuralFeature();
264       Object JavaDoc value = entry.getValue();
265       NotificationImpl notification =
266         feature.isMany() ?
267           createNotification
268             (Notification.REMOVE,
269              feature,
270              value,
271              null,
272              indexOf(feature, value),
273              true) :
274           createNotification
275             (feature.isUnsettable() ? Notification.UNSET : Notification.SET,
276              feature,
277              value,
278              feature.getDefaultValue(),
279              Notification.NO_INDEX,
280              true);
281
282       if (notifications != null)
283       {
284         notifications.add(notification);
285       }
286       else
287       {
288         notifications = notification;
289       }
290     }
291     return notifications;
292   }
293
294   public NotificationChain inverseRemove(Object JavaDoc object, NotificationChain notifications)
295   {
296     Entry entry = (Entry)object;
297     EStructuralFeature feature = entry.getEStructuralFeature();
298     if (feature instanceof EReference)
299     {
300       EReference eReference = (EReference)feature;
301       EReference eOpposite = eReference.getEOpposite();
302       if (eOpposite != null)
303       {
304         InternalEObject internalEObject = (InternalEObject)entry.getValue();
305         if (internalEObject != null)
306         {
307           notifications =
308             internalEObject.eInverseRemove
309               (owner,
310                internalEObject.eClass().getFeatureID(eOpposite),
311                null,
312                notifications);
313         }
314       }
315       else if (eReference.isContainment())
316       {
317         InternalEObject internalEObject = (InternalEObject)entry.getValue();
318         if (internalEObject != null)
319         {
320           int containmentFeatureID = owner.eClass().getFeatureID(eReference);
321           notifications =
322             internalEObject.eInverseRemove
323               (owner,
324                InternalEObject.EOPPOSITE_FEATURE_BASE - (containmentFeatureID == -1 ? featureID : containmentFeatureID),
325                null,
326                notifications);
327         }
328       }
329     }
330     return notifications;
331   }
332
333   public NotificationChain shadowSet(Object JavaDoc oldObject, Object JavaDoc newObject, NotificationChain notifications)
334   {
335     if (isNotificationRequired())
336     {
337       Entry entry = (Entry)oldObject;
338       EStructuralFeature feature = entry.getEStructuralFeature();
339       Object JavaDoc oldValue = entry.getValue();
340       Object JavaDoc newValue = ((Entry)newObject).getValue();
341       NotificationImpl notification =
342         createNotification
343           (Notification.SET,
344            feature,
345            oldValue,
346            newValue,
347            feature.isMany() ? indexOf(feature, newValue) : Notification.NO_INDEX,
348            true);
349
350       if (notifications != null)
351       {
352         notifications.add(notification);
353       }
354       else
355       {
356         notifications = notification;
357       }
358     }
359     return notifications;
360   }
361
362   public NotificationChain inverseTouch(Object JavaDoc object, NotificationChain notifications)
363   {
364     if (isNotificationRequired())
365     {
366       Entry entry = (Entry)object;
367       EStructuralFeature feature = entry.getEStructuralFeature();
368       Object JavaDoc value = entry.getValue();
369       NotificationImpl notification =
370         createNotification
371           (Notification.SET,
372            feature,
373            value,
374            value,
375            feature.isMany() ? indexOf(feature, value) : Notification.NO_INDEX,
376            true);
377   
378       if (notifications != null)
379       {
380         notifications.add(notification);
381       }
382       else
383       {
384         notifications = notification;
385       }
386     }
387
388     return notifications;
389   }
390
391   public Object JavaDoc move(int targetIndex, int sourceIndex)
392   {
393     if (isNotificationRequired())
394     {
395       Entry [] entries = (Entry[])data;
396       Entry sourceEntry = entries[sourceIndex];
397       EStructuralFeature feature = sourceEntry.getEStructuralFeature();
398       if (isMany(feature))
399       {
400         FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
401         int featureTargetIndex = -1;
402         int featureSourceIndex = -1;
403         int count = 0;
404         for (int i = 0; i < size; ++i)
405         {
406           Entry entry = entries[i];
407           if (i == targetIndex)
408           {
409             featureTargetIndex = count;
410           }
411           if (i == sourceIndex)
412           {
413             featureSourceIndex = count;
414           }
415           if (validator.isValid(entry.getEStructuralFeature()))
416           {
417             ++count;
418           }
419         }
420
421         Object JavaDoc result = doMove(targetIndex, sourceIndex);
422         if (featureSourceIndex != featureTargetIndex)
423         {
424           dispatchNotification
425             (new ENotificationImpl
426                (owner,
427                 Notification.MOVE,
428                 feature,
429                 new Integer JavaDoc(featureSourceIndex),
430                 sourceEntry.getValue(),
431                 featureTargetIndex));
432         }
433         return result;
434       }
435       else
436       {
437         return doMove(targetIndex, sourceIndex);
438       }
439     }
440     else
441     {
442       return doMove(targetIndex, sourceIndex);
443     }
444   }
445
446   protected Object JavaDoc doMove(int targetIndex, int sourceIndex)
447   {
448     return super.move(targetIndex, sourceIndex);
449   }
450
451   public Object JavaDoc set(int index, Object JavaDoc object)
452   {
453     Entry entry = (Entry)object;
454     EStructuralFeature entryFeature = entry.getEStructuralFeature();
455     if (isMany(entryFeature))
456     {
457       if (entryFeature.isUnique())
458       {
459         Entry [] entries = (Entry[])data;
460         for (int i = 0; i < size; ++i)
461         {
462           Entry otherEntry = entries[i];
463           if (otherEntry.equals(entry) && i != index)
464           {
465             throw new IllegalArgumentException JavaDoc("The 'no duplicates' constraint is violated");
466           }
467         }
468       }
469     }
470     else
471     {
472       FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), entryFeature);
473       Entry [] entries = (Entry[])data;
474       for (int i = 0; i < size; ++i)
475       {
476         Entry otherEntry = entries[i];
477         if (validator.isValid(otherEntry.getEStructuralFeature()) && i != index)
478         {
479           throw new IllegalArgumentException JavaDoc("The multiplicity constraint is violated");
480         }
481       }
482     }
483
484     return doSet(index, object);
485   }
486
487   public Object JavaDoc doSet(int index, Object JavaDoc object)
488   {
489     return super.set(index, object);
490   }
491
492   public boolean add(Object JavaDoc object)
493   {
494     Entry entry = (Entry)object;
495     EStructuralFeature entryFeature = entry.getEStructuralFeature();
496     if (isMany(entryFeature))
497     {
498       if (entryFeature.isUnique() && contains(entryFeature, entry.getValue()))
499       {
500         return false;
501       }
502     }
503     else
504     {
505       FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), entryFeature);
506       Entry [] entries = (Entry[])data;
507       for (int i = 0; i < size; ++i)
508       {
509         Entry otherEntry = entries[i];
510         if (validator.isValid(otherEntry.getEStructuralFeature()))
511         {
512           if (otherEntry.equals(entry))
513           {
514             return false;
515           }
516           else
517           {
518             doSet(i, object);
519             return true;
520           }
521         }
522       }
523     }
524
525     return doAdd(object);
526   }
527
528   protected boolean doAdd(Object JavaDoc object)
529   {
530     return super.add(object);
531   }
532
533   public void add(int index, Object JavaDoc object)
534   {
535     Entry entry = (Entry)object;
536     EStructuralFeature entryFeature = entry.getEStructuralFeature();
537     if (isMany(entryFeature))
538     {
539       if (entryFeature.isUnique())
540       {
541         Entry [] entries = (Entry[])data;
542         for (int i = 0; i < size; ++i)
543         {
544           Entry otherEntry = entries[i];
545           if (otherEntry.equals(entry) && i != index)
546           {
547             throw new IllegalArgumentException JavaDoc("The 'no duplicates' constraint is violated");
548           }
549         }
550       }
551     }
552     else
553     {
554       FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), entryFeature);
555       Entry [] entries = (Entry[])data;
556       for (int i = 0; i < size; ++i)
557       {
558         Entry otherEntry = entries[i];
559         if (validator.isValid(otherEntry.getEStructuralFeature()))
560         {
561           throw new IllegalArgumentException JavaDoc("The multiplicity constraint is violated");
562         }
563       }
564     }
565
566     doAdd(index, object);
567   }
568
569   public void doAdd(int index, Object JavaDoc object)
570   {
571     super.add(index, object);
572   }
573
574   public boolean addAll(Collection JavaDoc collection)
575   {
576     Collection JavaDoc uniqueCollection = new BasicEList(collection.size());
577     for (Iterator JavaDoc i = collection.iterator(); i.hasNext(); )
578     {
579       Entry entry = (Entry)i.next();
580       EStructuralFeature entryFeature = entry.getEStructuralFeature();
581       if (isMany(entryFeature))
582       {
583         if (!entryFeature.isUnique() || !contains(entryFeature, entry.getValue()) && !uniqueCollection.contains(entry))
584         {
585           uniqueCollection.add(entry);
586         }
587       }
588       else
589       {
590         FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), entryFeature);
591         Entry [] entries = (Entry[])data;
592         boolean include = true;
593         for (int j = 0; j < size; ++j)
594         {
595           Entry otherEntry = entries[j];
596           if (validator.isValid(otherEntry.getEStructuralFeature()))
597           {
598             doSet(j, entry);
599             include = false;
600             break;
601           }
602         }
603         if (include)
604         {
605           uniqueCollection.add(entry);
606         }
607       }
608     }
609
610     return doAddAll(uniqueCollection);
611   }
612
613   public boolean doAddAll(Collection JavaDoc collection)
614   {
615     return super.addAll(collection);
616   }
617
618   public boolean addAll(int index, Collection JavaDoc collection)
619   {
620     Collection JavaDoc uniqueCollection = new BasicEList(collection.size());
621     for (Iterator JavaDoc i = collection.iterator(); i.hasNext(); )
622     {
623       Entry entry = (Entry)i.next();
624       EStructuralFeature entryFeature = entry.getEStructuralFeature();
625       if (isMany(entryFeature))
626       {
627         if (!entryFeature.isUnique() || !contains(entryFeature, entry.getValue()) && !uniqueCollection.contains(entry))
628         {
629           uniqueCollection.add(entry);
630         }
631       }
632       else
633       {
634         FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), entryFeature);
635         Entry [] entries = (Entry[])data;
636         boolean include = true;
637         for (int j = 0; j < size; ++j)
638         {
639           Entry otherEntry = entries[j];
640           if (validator.isValid(otherEntry.getEStructuralFeature()))
641           {
642             doSet(j, entry);
643             include = false;
644             break;
645           }
646         }
647         if (include)
648         {
649           uniqueCollection.add(entry);
650         }
651       }
652     }
653
654     return doAddAll(index, uniqueCollection);
655   }
656
657   public boolean doAddAll(int index, Collection JavaDoc collection)
658   {
659     return super.addAll(index, collection);
660   }
661
662   public int size(EStructuralFeature feature)
663   {
664     FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
665     int result = 0;
666     Entry [] entries = (Entry[])data;
667     for (int i = 0; i < size; ++i)
668     {
669       Entry entry = entries[i];
670       if (validator.isValid(entry.getEStructuralFeature()))
671       {
672         ++result;
673       }
674     }
675     return result;
676   }
677
678   public boolean isEmpty(EStructuralFeature feature)
679   {
680     FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
681     Entry [] entries = (Entry[])data;
682     for (int i = 0; i < size; ++i)
683     {
684       Entry entry = entries[i];
685       if (validator.isValid(entry.getEStructuralFeature()))
686       {
687         return false;
688       }
689     }
690     return true;
691   }
692
693   public boolean contains(EStructuralFeature feature, Object JavaDoc object)
694   {
695     FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
696     Entry [] entries = (Entry[])data;
697     if (FeatureMapUtil.isFeatureMap(feature))
698     {
699       for (int i = 0; i < size; ++i)
700       {
701         Entry entry = entries[i];
702         if (validator.isValid(entry.getEStructuralFeature()) && entry.equals(object))
703         {
704           return true;
705         }
706       }
707     }
708     else if (object != null)
709     {
710       for (int i = 0; i < size; ++i)
711       {
712         Entry entry = entries[i];
713         if (validator.isValid(entry.getEStructuralFeature()) && object.equals(entry.getValue()))
714         {
715           return true;
716         }
717       }
718     }
719     else
720     {
721       for (int i = 0; i < size; ++i)
722       {
723         Entry entry = entries[i];
724         if (validator.isValid(entry.getEStructuralFeature()) && entry.getValue() == null)
725         {
726           return false;
727         }
728       }
729     }
730
731     return false;
732   }
733
734   public boolean containsAll(EStructuralFeature feature, Collection JavaDoc collection)
735   {
736     for (Iterator JavaDoc i = collection.iterator(); i.hasNext(); )
737     {
738       if (!contains(feature, i.next()))
739       {
740         return false;
741       }
742     }
743
744     return true;
745   }
746
747   public int indexOf(EStructuralFeature feature, Object JavaDoc object)
748   {
749     FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
750     int result = 0;
751     Entry [] entries = (Entry[])data;
752     if (FeatureMapUtil.isFeatureMap(feature))
753     {
754       for (int i = 0; i < size; ++i)
755       {
756         Entry entry = entries[i];
757         if (validator.isValid(entry.getEStructuralFeature()))
758         {
759           if (entry.equals(object))
760           {
761             return result;
762           }
763           ++result;
764         }
765       }
766     }
767     else if (object != null)
768     {
769       for (int i = 0; i < size; ++i)
770       {
771         Entry entry = entries[i];
772         if (validator.isValid(entry.getEStructuralFeature()))
773         {
774           if (object.equals(entry.getValue()))
775           {
776             return result;
777           }
778           ++result;
779         }
780       }
781     }
782     else
783     {
784       for (int i = 0; i < size; ++i)
785       {
786         Entry entry = entries[i];
787         if (validator.isValid(entry.getEStructuralFeature()))
788         {
789           if (entry.getValue() == null)
790           {
791             return result;
792           }
793           ++result;
794         }
795       }
796     }
797
798     return -1;
799   }
800
801   public int lastIndexOf(EStructuralFeature feature, Object JavaDoc object)
802   {
803     FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
804     int result = -1;
805     int count = 0;
806     Entry [] entries = (Entry[])data;
807     if (FeatureMapUtil.isFeatureMap(feature))
808     {
809       for (int i = 0; i < size; ++i)
810       {
811         Entry entry = entries[i];
812         if (validator.isValid(entry.getEStructuralFeature()))
813         {
814           if (entry.equals(object))
815           {
816             result = count;
817           }
818           ++count;
819         }
820       }
821     }
822     else if (object != null)
823     {
824       for (int i = 0; i < size; ++i)
825       {
826         Entry entry = entries[i];
827         if (validator.isValid(entry.getEStructuralFeature()))
828         {
829           if (object.equals(entry.getValue()))
830           {
831             result = count;
832           }
833           ++count;
834         }
835       }
836     }
837     else
838     {
839       for (int i = 0; i < size; ++i)
840       {
841         Entry entry = entries[i];
842         if (validator.isValid(entry.getEStructuralFeature()))
843         {
844           if (entry.getValue() == null)
845           {
846             result = count;
847           }
848           ++count;
849         }
850       }
851     }
852
853     return result;
854   }
855
856   public Iterator JavaDoc iterator(EStructuralFeature feature)
857   {
858     return
859       feature instanceof EReference && ((EReference)feature).isResolveProxies() ?
860         new ResolvingFeatureEIterator(feature, this) :
861         new FeatureEIterator(feature, this);
862   }
863
864   public ListIterator JavaDoc listIterator(EStructuralFeature feature)
865   {
866     return
867       feature instanceof EReference && ((EReference)feature).isResolveProxies() ?
868         new ResolvingFeatureEIterator(feature, this) :
869         new FeatureEIterator(feature, this);
870   }
871
872   public ListIterator JavaDoc listIterator(EStructuralFeature feature, int index)
873   {
874     ListIterator JavaDoc result =
875       feature instanceof EReference && ((EReference)feature).isResolveProxies() ?
876         new ResolvingFeatureEIterator(feature, this) :
877         new FeatureEIterator(feature, this);
878     for (int i = 0; i < index; ++i)
879     {
880       result.next();
881     }
882     return result;
883   }
884
885   public ValueListIterator valueListIterator()
886   {
887     return new ValueListIteratorImpl();
888   }
889   
890   public ValueListIterator valueListIterator(int index)
891   {
892     return new ValueListIteratorImpl(index);
893   }
894   
895   protected class ValueListIteratorImpl extends EListIterator implements ValueListIterator
896   {
897     public ValueListIteratorImpl()
898     {
899       super();
900     }
901     
902     public ValueListIteratorImpl(int index)
903     {
904       super(index);
905     }
906     
907     public EStructuralFeature feature()
908     {
909       if (lastCursor == -1)
910       {
911         throw new IllegalStateException JavaDoc();
912       }
913       return getEStructuralFeature(lastCursor);
914     }
915     
916     public Object JavaDoc next()
917     {
918       return ((Entry)super.next()).getValue();
919     }
920     
921     public Object JavaDoc previous()
922     {
923       return ((Entry)super.next()).getValue();
924     }
925
926     public void add(Object JavaDoc value)
927     {
928       super.add(FeatureMapUtil.createEntry(feature(), value));
929     }
930     
931     public void add(EStructuralFeature eStructuralFeature, Object JavaDoc value)
932     {
933       super.add(FeatureMapUtil.createEntry(eStructuralFeature, value));
934     }
935   }
936   
937 /*
938   public List subList(EStructuralFeature feature, int from, int to)
939   {
940     return null;
941   }
942 */

943
944   public EList list(EStructuralFeature feature)
945   {
946     return
947       FeatureMapUtil.isFeatureMap(feature) ?
948         new FeatureMapUtil.FeatureFeatureMap(f