/*
* grEMF
*
* Copyright (C) 2006-2012 Institute for Software Technology
* University of Koblenz-Landau, Germany
* ist@uni-koblenz.de
*
* For bug reports, documentation and further information, visit
*
* https://github.com/jgralab/gremf
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, see <http://www.gnu.org/licenses>.
*
* Additional permission under GNU GPL version 3 section 7
*
* If you modify this Program, or any covered work, by linking or combining
* it with Eclipse (or a modified version of that program or an Eclipse
* plugin), containing parts covered by the terms of the Eclipse Public
* License (EPL), the licensors of this Program grant you additional
* permission to convey the resulting work. Corresponding Source for a
* non-source form of such a combination shall include the source code for
* the parts of JGraLab used as well as that of the covered work.
*/
package de.uni_koblenz.gremf.collection;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.ECollections;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.util.InternalEList;
import de.uni_koblenz.gremf.impl.GrEMFGraphImpl;
import de.uni_koblenz.gremf.impl.GrEMFVertexImpl;
import de.uni_koblenz.gremf.schema.impl.GrEMFIncidenceClassImpl;
import de.uni_koblenz.jgralab.Edge;
import de.uni_koblenz.jgralab.EdgeDirection;
import de.uni_koblenz.jgralab.Vertex;
import de.uni_koblenz.jgralab.impl.InternalEdge;
import de.uni_koblenz.jgralab.schema.EdgeClass;
import de.uni_koblenz.jgralab.schema.IncidenceDirection;
public class GrEMFIncidencesListProxy implements EList<EObject>,
InternalEList<EObject> {
private GrEMFIncidenceClassImpl feature;
private GrEMFVertexImpl gremfVertex;
private EdgeClass edgeClass;
private EdgeDirection edgeDirection;
public GrEMFIncidencesListProxy(EObject o, EReference f) {
this.gremfVertex = (GrEMFVertexImpl) o;
this.feature = (GrEMFIncidenceClassImpl) f;
this.edgeClass = this.feature.getEdgeClass();
if (this.feature.getDirection().equals(IncidenceDirection.IN)) {
this.edgeDirection = EdgeDirection.OUT;
} else {
this.edgeDirection = EdgeDirection.IN;
}
}
// --------------------------------------------------------------------------
// Methods from interface
// java.util.List
// --------------------------------------------------------------------------
@Override
public boolean add(EObject e) {
this.createEdge(e);
return true;
}
@Override
public void add(int index, EObject element) {
int degree = this.gremfVertex.getDegree(this.edgeClass,
this.edgeDirection);
if (index > degree) {
throw new IndexOutOfBoundsException();
}
Edge e = this.createEdge(element);
if (index != (degree - 1)) {
// Edge edgeAtIndex = this.getEdge(index)
Edge edgeAtIndex = this.getEdge(index).getNormalEdge();
this.gremfVertex.putIncidenceBefore((InternalEdge) edgeAtIndex,
(InternalEdge) e);
}
}
@Override
public boolean addAll(Collection<? extends EObject> c) {
int size = c.size();
if (size > 1) {
this.disableECANotification();
}
for (EObject ob : c) {
this.createEdge(ob);
if (size > 1) {
this.notifyEOppositeAdd(ob);
}
}
if ((size > 1) && this.gremfVertex.eNotificationRequired()) {
this.gremfVertex.eNotify(new ENotificationImpl(this.gremfVertex,
Notification.ADD_MANY, this.feature, null, c, this.size()
- size));
}
this.enableECANotification();
return true;
}
@SuppressWarnings("unchecked")
private void notifyEOppositeAdd(EObject ob) {
if (((InternalEObject) ob).eNotificationRequired()) {
if (this.feature.getEOpposite() != null) {
ob.eNotify(new ENotificationImpl((InternalEObject) ob,
Notification.ADD, this.feature.getEOpposite(), null,
this.gremfVertex, ((List<EObject>) ob.eGet(this.feature
.getEOpposite())).size()));
}
}
}
@Override
public boolean addAll(int index, Collection<? extends EObject> c) {
int oldDegree = this.gremfVertex.getDegree(this.edgeClass,
this.edgeDirection);
if (index > oldDegree) {
throw new IndexOutOfBoundsException();
} else if (index == oldDegree) {
this.addAll(c);
} else {
this.disableECANotification();
Edge edgeAtIndex = this.getEdge(index);
for (EObject ob : c) {
Edge e = this.createEdge(ob);
this.gremfVertex.putIncidenceBefore((InternalEdge) edgeAtIndex,
(InternalEdge) e);
this.notifyEOppositeAdd(ob);
}
if (this.gremfVertex.eNotificationRequired()) {
int size = c.size();
if (size > 1) {
this.gremfVertex.eNotify(new ENotificationImpl(
this.gremfVertex, Notification.ADD_MANY,
this.feature, null, c, index));
} else if (size == 1) {
this.gremfVertex.eNotify(new ENotificationImpl(
this.gremfVertex, Notification.ADD, this.feature,
null, c.iterator().next(), index));
}
}
this.enableECANotification();
}
return true;
}
@Override
public void clear() {
ArrayList<EObject> list = new ArrayList<EObject>();
ArrayList<Edge> toDelete = new ArrayList<Edge>();
this.disableECANotification();
if (this.feature.getDirection() == IncidenceDirection.IN) {
for (Edge e : this.gremfVertex.incidences(this.edgeClass,
this.edgeDirection)) {
toDelete.add(e);
list.add((EObject) e.getOmega());
}
} else {
for (Edge e : this.gremfVertex.incidences(this.edgeClass,
this.edgeDirection)) {
toDelete.add(e);
list.add((EObject) e.getAlpha());
}
}
for (Edge e : toDelete) {
e.delete();
}
if (this.gremfVertex.eNotificationRequired()) {
int size = list.size();
if (size > 1) {
this.gremfVertex.eNotify(new ENotificationImpl(
this.gremfVertex, Notification.REMOVE_MANY,
this.feature, list, null));
} else if (size == 1) {
this.gremfVertex.eNotify(new ENotificationImpl(
this.gremfVertex, Notification.REMOVE, this.feature,
list.get(0), null, 0));
}
}
this.enableECANotification();
}
@Override
public boolean contains(Object o) {
if (this.feature.getDirection() == IncidenceDirection.OUT) {
for (Edge edge : this.gremfVertex.incidences(this.edgeClass,
this.edgeDirection)) {
if (edge.getAlpha().equals(o)) {
return true;
}
}
} else {
for (Edge edge : this.gremfVertex.incidences(this.edgeClass,
this.edgeDirection)) {
if (edge.getOmega().equals(o)) {
return true;
}
}
}
return false;
}
@Override
public boolean containsAll(Collection<?> c) {
for (Object o : c) {
if (!this.contains(o)) {
return false;
}
}
return true;
}
@Override
public EObject get(int index) {
int n = 0;
if (this.feature.getDirection() == IncidenceDirection.OUT) {
for (Edge e : this.gremfVertex.incidences(this.edgeClass,
this.edgeDirection)) {
if (n == index) {
return (EObject) e.getAlpha();
}
n++;
}
} else {
for (Edge e : this.gremfVertex.incidences(this.edgeClass,
this.edgeDirection)) {
if (n == index) {
return (EObject) e.getOmega();
}
n++;
}
}
throw new IndexOutOfBoundsException();
}
@Override
public int indexOf(Object o) {
int n = 0;
if (this.feature.getDirection() == IncidenceDirection.OUT) {
for (Edge e : this.gremfVertex.incidences(this.edgeClass,
this.edgeDirection)) {
if (e.getAlpha().equals(o)) {
return n;
}
n++;
}
} else {
for (Edge e : this.gremfVertex.incidences(this.edgeClass,
this.edgeDirection)) {
if (e.getOmega().equals(o)) {
return n;
}
n++;
}
}
return -1;
}
@Override
public boolean isEmpty() {
return !this.gremfVertex.incidences(this.edgeClass, this.edgeDirection)
.iterator().hasNext();
// return this.gremfVertex.getDegree(this.edgeClass, this.edgeDirection)
// < 1;
}
@Override
public Iterator<EObject> iterator() {
if (this.isEmpty()) {
return (new BasicEList<EObject>()).iterator();
}
return this.createIncidenceList().iterator();
// return (Iterator<EObject>) this.gremfVertex.adjacences(
// this.feature.getRolename()).iterator();
}
@Override
public int lastIndexOf(Object o) {
return this.createIncidenceList().lastIndexOf(o);
// return this.gremfVertex.adjacences(this.feature.getRolename())
// .lastIndexOf(o);
}
@Override
public ListIterator<EObject> listIterator() {
return this.listIterator(0);
}
@SuppressWarnings("unchecked")
@Override
public ListIterator<EObject> listIterator(int index) {
if (this.isEmpty()) {
return (ListIterator<EObject>) ECollections.EMPTY_ELIST
.listIterator();
}
return this.createIncidenceList().listIterator(index);
// return (ListIterator<EObject>) this.gremfVertex.adjacences(
// this.feature.getRolename()).listIterator(index);
}
private AbstractList<EObject> createIncidenceList() {
if (this.feature.getDirection() == IncidenceDirection.OUT) {
return this.createOutIncidenceList();
} else {
return this.createInIcidenceList();
}
}
private AbstractList<EObject> createInIcidenceList() {
AbstractList<EObject> incidences = new ArrayList<EObject>();
for (Edge e : this.gremfVertex.incidences(this.edgeClass,
this.edgeDirection)) {
incidences.add((EObject) e.getOmega());
}
return incidences;
}
private AbstractList<EObject> createOutIncidenceList() {
AbstractList<EObject> incidences = new ArrayList<EObject>();
for (Edge e : this.gremfVertex.incidences(this.edgeClass,
this.edgeDirection)) {
incidences.add((EObject) e.getAlpha());
}
return incidences;
}
private int getEOppositeIndex(Edge e, GrEMFVertexImpl target) {
if (this.feature.getDirection() == IncidenceDirection.OUT) {
int i = 0;
for (Edge edge : target.incidences(this.edgeClass,
EdgeDirection.OUT)) {
if (e.equals(edge)) {
return i;
}
i++;
}
} else {
int i = 0;
for (Edge edge : target
.incidences(this.edgeClass, EdgeDirection.IN)) {
if (e.equals(edge)) {
return i;
}
i++;
}
}
return -1;
}
@Override
public boolean remove(Object o) {
if (this.feature.getDirection() == IncidenceDirection.OUT) {
int n = 0;
for (Edge e : this.gremfVertex.incidences(this.edgeClass,
this.edgeDirection)) {
if (e.getAlpha().equals(o)) {
this.disableECANotification();
int oppindex = this.getEOppositeIndex(e,
(GrEMFVertexImpl) o);
e.delete();
this.notifyRemoveWithEOpp(o, n, oppindex);
this.enableECANotification();
return true;
}
n++;
}
} else {
int n = 0;
for (Edge e : this.gremfVertex.incidences(this.edgeClass,
this.edgeDirection)) {
if (e.getOmega().equals(o)) {
this.disableECANotification();
int oppindex = this.getEOppositeIndex(e,
(GrEMFVertexImpl) o);
e.delete();
this.notifyRemoveWithEOpp(o, n, oppindex);
this.enableECANotification();
return true;
}
n++;
}
}
return false;
}
private void notifyRemoveWithEOpp(Object o, int n, int oppindex) {
if (this.gremfVertex.eNotificationRequired()) {
this.gremfVertex.eNotify(new ENotificationImpl(this.gremfVertex,
Notification.REMOVE, this.feature, o, null, n));
}
if (((InternalEObject) o).eNotificationRequired()) {
if (this.feature.getEOpposite() != null) {
((EObject) o).eNotify(new ENotificationImpl(
(InternalEObject) o, Notification.REMOVE, this.feature
.getEOpposite(), this.gremfVertex, null,
oppindex));
}
}
}
@Override
public EObject remove(int index) {
int n = 0;
if (this.feature.getDirection() == IncidenceDirection.OUT) {
for (Edge e : this.gremfVertex.incidences(this.edgeClass,
this.edgeDirection)) {
if (index == n) {
this.disableECANotification();
Vertex alpha = e.getAlpha();
int oppindex = this.getEOppositeIndex(e,
(GrEMFVertexImpl) alpha);
e.delete();
this.notifyRemoveWithEOpp(alpha, n, oppindex);
this.enableECANotification();
return (EObject) alpha;
}
n++;
}
} else {
for (Edge e : this.gremfVertex.incidences(this.edgeClass,
this.edgeDirection)) {
if (index == n) {
this.disableECANotification();
Vertex omega = e.getOmega();
int oppindex = this.getEOppositeIndex(e,
(GrEMFVertexImpl) omega);
e.delete();
this.notifyRemoveWithEOpp(omega, n, oppindex);
this.enableECANotification();
return (EObject) omega;
}
n++;
}
}
throw new IndexOutOfBoundsException();
}
@Override
public boolean removeAll(Collection<?> c) {
this.disableECANotification();
boolean changed = false;
ArrayList<Integer> deletedIndices = new ArrayList<Integer>();
ArrayList<Edge> toDelete = new ArrayList<Edge>();
ArrayList<EObject> deletedEObjects = new ArrayList<EObject>();
int i = 0;
if (this.feature.getDirection() == IncidenceDirection.IN) {
for (Edge e : this.gremfVertex.incidences(this.edgeClass,
this.edgeDirection)) {
if (c.contains(e.getOmega())) {
toDelete.add(e);
deletedIndices.add(i);
deletedEObjects.add((EObject) e.getOmega());
changed = true;
}
i++;
}
for (Edge e : toDelete) {
EObject target = (EObject) e.getOmega();
int oppIndex = this.getEOppositeIndex(e,
(GrEMFVertexImpl) target);
e.delete();
this.notifyEOppositeRemove(target, oppIndex);
}
} else {
for (Edge e : this.gremfVertex.incidences(this.edgeClass,
this.edgeDirection)) {
if (c.contains(e.getAlpha())) {
toDelete.add(e);
deletedIndices.add(i);
deletedEObjects.add((EObject) e.getAlpha());
changed = true;
}
i++;
}
for (Edge e : toDelete) {
EObject target = (EObject) e.getAlpha();
int oppIndex = this.getEOppositeIndex(e,
(GrEMFVertexImpl) target);
e.delete();
this.notifyEOppositeRemove(target, oppIndex);
}
}
if (this.gremfVertex.eNotificationRequired()) {
int[] intArray = new int[deletedIndices.size()];
for (i = 0; i < intArray.length; i++) {
intArray[i] = deletedIndices.get(i);
}
if (intArray.length > 1) {
this.gremfVertex.eNotify(new ENotificationImpl(
this.gremfVertex, Notification.REMOVE_MANY,
this.feature, deletedEObjects, intArray, deletedIndices
.get(0)));
} else if (intArray.length == 1) {
this.gremfVertex.eNotify(new ENotificationImpl(
this.gremfVertex, Notification.REMOVE, this.feature,
deletedEObjects.get(0), null, deletedIndices.get(0)));
}
}
this.enableECANotification();
return changed;
}
private void notifyEOppositeRemove(EObject target, int oppIndex) {
if (((InternalEObject) target).eNotificationRequired()) {
if (this.feature.getEOpposite() != null) {
target.eNotify(new ENotificationImpl((InternalEObject) target,
Notification.REMOVE, this.feature.getEOpposite(),
this.gremfVertex, null, oppIndex));
}
}
}
@Override
public boolean retainAll(Collection<?> c) {
boolean changed = false;
ArrayList<Edge> toDelete = new ArrayList<Edge>();
ArrayList<Integer> deleteIndices = new ArrayList<Integer>();
this.disableECANotification();
if (this.feature.getDirection() == IncidenceDirection.OUT) {
int i = 0;
for (Edge e : this.gremfVertex.incidences(this.edgeClass,
this.edgeDirection)) {
if (!c.contains(e.getAlpha())) {
toDelete.add(e);
deleteIndices.add(i);
changed = true;
}
i++;
}
for (i = toDelete.size() - 1; i >= 0; i--) {
Edge e = toDelete.get(i);
Vertex alpha = e.getAlpha();
int oppIndex = this.getEOppositeIndex(e,
(GrEMFVertexImpl) alpha);
e.delete();
this.notifyRemoveWithEOpp(alpha, deleteIndices.get(i), oppIndex);
}
} else {
int i = 0;
for (Edge e : this.gremfVertex.incidences(this.edgeClass,
this.edgeDirection)) {
if (!c.contains(e.getOmega())) {
toDelete.add(e);
deleteIndices.add(i);
changed = true;
}
i++;
}
for (i = toDelete.size() - 1; i >= 0; i--) {
Edge e = toDelete.get(i);
Vertex omega = e.getOmega();
int oppIndex = this.getEOppositeIndex(e,
(GrEMFVertexImpl) omega);
e.delete();
this.notifyRemoveWithEOpp(omega, deleteIndices.get(i), oppIndex);
}
}
this.enableECANotification();
return changed;
}
@Override
public EObject set(int index, EObject element) {
this.disableECANotification();
Edge e = this.getEdge(index);
Edge newEdge = this.createEdge(element);
this.gremfVertex.putIncidenceBefore((InternalEdge) e,
(InternalEdge) newEdge);
Vertex oldValue;
Vertex newValue;
if (this.feature.getDirection().equals(IncidenceDirection.OUT)) {
oldValue = e.getAlpha();
newValue = newEdge.getAlpha();
} else {
oldValue = e.getOmega();
newValue = newEdge.getOmega();
}
int oppIndex = this.getEOppositeIndex(e, (GrEMFVertexImpl) oldValue);
e.delete();
if (this.gremfVertex.eNotificationRequired()) {
this.gremfVertex.eNotify(new ENotificationImpl(this.gremfVertex,
Notification.SET, this.feature, oldValue, newValue));
}
this.notifyEOppositeAdd((EObject) newValue);
this.notifyEOppositeRemove((EObject) oldValue, oppIndex);
this.enableECANotification();
return (EObject) oldValue;
}
@Override
public int size() {
return this.gremfVertex.getDegree(this.edgeClass, this.edgeDirection);
// return
// this.gremfVertex.adjacences(this.feature.getRolename()).size();
}
@Override
public List<EObject> subList(int fromIndex, int toIndex) {
return this.createIncidenceList().subList(fromIndex, toIndex);
// return (List<EObject>) this.gremfVertex.adjacences(
// this.feature.getRolename()).subList(fromIndex, toIndex);
}
@Override
public EObject[] toArray() {
return this.createIncidenceList().toArray(new EObject[0]);
// EObject[] array = this.gremfVertex.adjacences(
// this.feature.getRolename()).toArray(new EObject[0]);
// return array;
}
@SuppressWarnings("unchecked")
@Override
public Object[] toArray(Object[] a) {
return this.createIncidenceList().toArray(a);
// return
// this.gremfVertex.adjacences(this.feature.getRolename()).toArray(
// a);
}
// --------------------------------------------------------------------------
// Methods from interface
// org.eclipse.emf.ecore.util.EList
// --------------------------------------------------------------------------
@Override
public void move(int newPosition, EObject object) {
if (!this.contains(object)) {
throw new ArrayIndexOutOfBoundsException(-1);
}
this.move(newPosition, this.indexOf(object));
}
@Override
public EObject move(int newPosition, int oldPosition) {
if (this.contains((newPosition < 0) || (oldPosition < 0)
|| (newPosition >= this.size()) || (newPosition >= this.size()))) {
throw new ArrayIndexOutOfBoundsException(-1);
}
Edge old = this.getEdge(newPosition);
Edge toBeMoved = this.getEdge(oldPosition);
this.gremfVertex.putIncidenceBefore((InternalEdge) old,
(InternalEdge) toBeMoved);
if (this.gremfVertex.eNotificationRequired()) {
if (this.feature.getDirection() == IncidenceDirection.IN) {
this.gremfVertex.eNotify(new ENotificationImpl(
this.gremfVertex, Notification.MOVE, this.feature,
oldPosition, toBeMoved.getOmega(), newPosition));
} else {
this.gremfVertex.eNotify(new ENotificationImpl(
this.gremfVertex, Notification.MOVE, this.feature,
oldPosition, toBeMoved.getAlpha(), newPosition));
}
}
if (this.feature.getDirection() == IncidenceDirection.IN) {
return (EObject) toBeMoved.getOmega();
} else {
return (EObject) toBeMoved.getAlpha();
}
}
// --------------------------------------------------------------------------
// Additional Methods for convenience
// to support others
// --------------------------------------------------------------------------
private void disableECANotification() {
((GrEMFGraphImpl) this.gremfVertex.getGraph()).getEdgeClassCondition()
.setCondition(false);
}
private void enableECANotification() {
((GrEMFGraphImpl) this.gremfVertex.getGraph()).getEdgeClassCondition()
.setCondition(true);
}
private Edge getEdge(int index) {
int i = 0;
for (Edge edge : this.gremfVertex.incidences(this.edgeClass,
this.edgeDirection)) {
if (i == index) {
return edge;
}
i++;
}
return null;
}
private Edge createEdge(EObject e) {
GrEMFIncidenceClassImpl inc = this.feature;
if (inc.getDirection().equals(IncidenceDirection.OUT)) {
return this.gremfVertex.getGraph().createEdge(this.edgeClass,
(GrEMFVertexImpl) e, this.gremfVertex);
} else {
return this.gremfVertex.getGraph().createEdge(this.edgeClass,
this.gremfVertex, (GrEMFVertexImpl) e);
}
}
// --------------------------------------------------------------------------
// Methods from interface
// java.lang.Object
// --------------------------------------------------------------------------
@Override
public String toString() {
StringBuilder rep = new StringBuilder().append('[');
if (this.feature.getDirection() == IncidenceDirection.IN) {
for (Edge e : this.gremfVertex.incidences(
this.feature.getEdgeClass(), EdgeDirection.OUT)) {
rep.append(e.getOmega()).append(',').append(' ');
}
} else {
for (Edge e : this.gremfVertex.incidences(
this.feature.getEdgeClass(), EdgeDirection.IN)) {
rep.append(e.getAlpha()).append(',').append(' ');
}
}
return rep.append(']').toString();
}
// --------------------------------------------------------------------------
// Methods from interface
// org.eclipse.emf.ecore.util.InternalEList
// --------------------------------------------------------------------------
@Override
public EObject basicGet(int index) {
return this.get(index);
}
@Override
public List<EObject> basicList() {
return ECollections.unmodifiableEList(this);
}
@Override
public Iterator<EObject> basicIterator() {
return this.iterator();
}
@Override
public ListIterator<EObject> basicListIterator() {
return this.listIterator();
}
@Override
public ListIterator<EObject> basicListIterator(int index) {
return this.listIterator(index);
}
@Override
public Object[] basicToArray() {
return this.toArray();
}
@SuppressWarnings("unchecked")
@Override
public <T> T[] basicToArray(T[] array) {
return (T[]) this.toArray(array);
}
@Override
public int basicIndexOf(Object object) {
return this.indexOf(object);
}
@Override
public int basicLastIndexOf(Object object) {
return this.lastIndexOf(object);
}
@Override
public boolean basicContains(Object object) {
return this.contains(object);
}
@Override
public boolean basicContainsAll(Collection<?> collection) {
return this.containsAll(collection);
}
@Override
public NotificationChain basicRemove(Object object,
NotificationChain notifications) {
this.remove(object);
return notifications;
}
@Override
public NotificationChain basicAdd(EObject object,
NotificationChain notifications) {
this.add(object);
return notifications;
}
@Override
public void addUnique(EObject object) {
this.add(object);
}
@Override
public void addUnique(int index, EObject object) {
this.add(index, object);
}
@Override
public boolean addAllUnique(Collection<? extends EObject> collection) {
return this.addAll(collection);
}
@Override
public boolean addAllUnique(int index,
Collection<? extends EObject> collection) {
return this.addAll(index, collection);
}
@Override
public EObject setUnique(int index, EObject object) {
return this.set(index, object);
}
}