/**
   * Returns a list that holds the opposite elements of the given reference for the given owner. The
   * opposite elements are those of type E that have the reference to owner.
   *
   * <p>The collection corresponding to opposite in the following picture is returned, for given
   * owner and reference.
   *
   * <pre>
   *    <b>opposite</b>            reference
   *  E ----------------------------- owner
   *  </pre>
   *
   * reference has to be a key of the map observedRefToOpposite.
   *
   * @param <E>
   * @param <E> The type of the elements in the collection.
   * @param dataClass The class of the elements in the collection.
   * @param owner The object whose list is retrieved.
   * @param reference The reference whose opposite reference is retrieved.
   * @return The opposite of reference for owner.
   */
  public <E> List<E> getOppositeList(
      Class<E> dataClass, InternalEObject owner, EReference reference) {
    EReference opposite = observedRefToOpposite.get(reference);
    if (opposite == null)
      throw new IllegalArgumentException(
          "This reference is not observed by this adapter: " + reference.toString());

    EObjectEList<E> result = new EObjectEList<E>(dataClass, owner, opposite.getFeatureID());

    for (Setting cur : getNonNavigableInverseReferences(owner, false)) {
      if (cur.getEStructuralFeature().equals(reference))
        result.add(dataClass.cast(cur.getEObject()));
    }

    return result;
  }
  private void adjustTransientOppositeReference(
      InternalEObject instance, InternalEObject object, EReference oppositeReference) {
    boolean wasDeliver = object.eDeliver(); // Disable notifications
    if (wasDeliver) {
      object.eSetDeliver(false);
    }

    try {
      if (oppositeReference.isMany()) {
        @SuppressWarnings("unchecked")
        InternalEList<Object> list = (InternalEList<Object>) object.eGet(oppositeReference);
        list.basicAdd(instance, null);
      } else {
        if (object.eGet(oppositeReference) != instance) {
          object.eInverseAdd(
              instance, oppositeReference.getFeatureID(), ((EObject) instance).getClass(), null);
        }
      }
    } finally {
      if (wasDeliver) {
        object.eSetDeliver(true);
      }
    }
  }