// @ requires ipEnum != null;
 // @ requires iEnum != null;
 // @ requires (ipEnum.moreElements || iEnum.moreElements) ==> k != null;
 protected JMLObjectToObjectRelationEnumerator(
     JMLObjectToObjectRelationImageEnumerator ipEnum, JMLObjectSetEnumerator iEnum, Object k) {
   // @ assume (ipEnum.moreElements || iEnum.moreElements) ==> k != null;
   // @ set owner = null;
   // @ set elementType = \type(JMLObjectObjectPair);
   // @ set returnsNull = false;
   imagePairEnum = (JMLObjectToObjectRelationImageEnumerator) ipEnum.clone();
   imageEnum = (JMLObjectSetEnumerator) iEnum.clone();
   key = k;
   // @ assume moreElements ==> key != null;
 }
 /*@ normal_behavior
 @   requires rel != null;
 @   assignable uniteratedPairs;
 @   assignable moreElements, elementType, returnsNull, owner;
 @   ensures uniteratedPairs.equals(rel.theRelation);
 @    ensures owner == null;
 @*/
 JMLObjectToObjectRelationEnumerator(
     /*@ non_null @*/
     JMLObjectToObjectRelation rel) {
   // @ set owner = null;
   // @ set elementType = \type(JMLObjectObjectPair);
   // @ set returnsNull = false;
   imagePairEnum = rel.imagePairs();
   if (imagePairEnum.hasMoreElements()) {
     JMLObjectValuePair p = imagePairEnum.nextImagePair();
     key = p.key;
     // @ assume key != null;
     // @ assume p.value != null;
     // @ assume p.value instanceof JMLObjectSet;
     imageEnum = ((JMLObjectSet) p.value).elements();
     // @ assume imageEnum.moreElements;
   } else {
     key = null;
     imageEnum = (new JMLObjectSet()).elements();
     // @ assume !imageEnum.moreElements;
   }
 }
 /*@ also
 @  public normal_behavior
 @    requires !uniteratedPairs.isEmpty();
 @    assignable uniteratedPairs;
 @    ensures \old(uniteratedPairs).has((JMLType)\result)
 @         && uniteratedPairs.
 @                equals(\old(uniteratedPairs).remove((JMLType)\result));
 @ also
 @  public exceptional_behavior
 @    requires uniteratedPairs.isEmpty();
 @    assignable \nothing;
 @    signals_only JMLNoSuchElementException;
 @*/
 public Object nextElement() throws JMLNoSuchElementException {
   if (imageEnum.hasMoreElements()) {
     Object v = imageEnum.nextElement();
     // @ assume v != null && v instanceof Object;
     return new JMLObjectObjectPair(key, (Object) v);
   } else if (imagePairEnum.hasMoreElements()) {
     Object p = imagePairEnum.nextElement();
     // @ assume p != null && p instanceof JMLObjectValuePair;
     JMLObjectValuePair imagePair = (JMLObjectValuePair) p;
     key = imagePair.key;
     // @ assume imagePair.value != null;
     // @ assume imagePair.value instanceof JMLObjectSet;
     imageEnum = ((JMLObjectSet) imagePair.value).elements();
     // @ assume imageEnum.moreElements;
     Object v = imageEnum.nextElement();
     // @ assume v != null && v instanceof Object;
     return new JMLObjectObjectPair(key, v);
   } else {
     throw new JMLNoSuchElementException();
   }
 }
 /*@ also
 @  public normal_behavior
 @    assignable \nothing;
 @    ensures \result == !uniteratedPairs.isEmpty();
 @*/
 public /*@ pure @*/ boolean hasMoreElements() {
   return (imagePairEnum.hasMoreElements() || imageEnum.hasMoreElements());
 }