KickJava   Java API By Example, From Geeks To Geeks.

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


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: DelegatingFeatureMap.java,v 1.18 2005/06/12 13:29:22 emerks Exp $
16  */

17 package org.eclipse.emf.ecore.util;
18
19
20
21 import java.util.Collection JavaDoc;
22 import java.util.Collections JavaDoc;
23 import java.util.Iterator JavaDoc;
24 import java.util.List JavaDoc;
25 import java.util.ListIterator JavaDoc;
26
27 import org.eclipse.emf.common.notify.Notification;
28 import org.eclipse.emf.common.notify.NotificationChain;
29 import org.eclipse.emf.common.notify.impl.NotificationImpl;
30 import org.eclipse.emf.common.util.BasicEList;
31 import org.eclipse.emf.common.util.EList;
32 import org.eclipse.emf.ecore.EClassifier;
33 import org.eclipse.emf.ecore.EObject;
34 import org.eclipse.emf.ecore.EReference;
35 import org.eclipse.emf.ecore.EStructuralFeature;
36 import org.eclipse.emf.ecore.InternalEObject;
37 import org.eclipse.emf.ecore.impl.ENotificationImpl;
38
39
40
41 public abstract class DelegatingFeatureMap extends DelegatingEcoreEList implements FeatureMap.Internal
42 {
43   protected final FeatureMapUtil.Validator featureMapValidator;
44   protected final EStructuralFeature eStructuralFeature;
45
46   public DelegatingFeatureMap(InternalEObject owner, int featureID)
47   {
48     super(owner);
49     this.eStructuralFeature = owner.eClass().getEStructuralFeature(featureID);
50     featureMapValidator = FeatureMapUtil.getValidator(owner.eClass(), getEStructuralFeature());
51   }
52
53   public DelegatingFeatureMap(InternalEObject owner, EStructuralFeature eStructuralFeature)
54   {
55     super(owner);
56     this.eStructuralFeature = eStructuralFeature;
57     featureMapValidator = FeatureMapUtil.getValidator(owner.eClass(), getEStructuralFeature());
58   }
59
60 /*
61   List theList = new java.util.ArrayList();
62   protected List delegateList()
63   {
64     return theList;
65   }
66 */

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