code: protected <T extends JvmTypeReference> T cloneAndAssociate(T original) {
  		final boolean canAssociate = languageInfo.isLanguage(original.eResource());
  		EcoreUtil.Copier copier = new EcoreUtil.Copier(false) {
  			private static final long serialVersionUID = 1L;
  
  			@Override/* @Nullable */ 
  			protected EObject createCopy(/* @Nullable */ EObject eObject) {
  				EObject result = super.createCopy(eObject);
  				if (result != null && eObject != null && !eObject.eIsProxy()) {
  					if (canAssociate)
  						associator.associate(eObject, result);
  				}
  				return result;
  			}
  			@Override
  			public EObject copy(/* @Nullable */ EObject eObject) {
  				EObject result = super.copy(eObject);
  				if (result instanceof JvmWildcardTypeReference) {
  					boolean upperBoundSeen = false;
  					for(JvmTypeConstraint constraint: ((JvmWildcardTypeReference) result).getConstraints()) {
  						if (constraint instanceof JvmUpperBound) {
  							upperBoundSeen = true;
  							break;
  						}
  					}
  					if (!upperBoundSeen) {
  						// no upper bound found - seems to be an invalid - assume object as upper bound
  						JvmTypeReference object = newObjectReference();
  						JvmUpperBound upperBound = typesFactory.createJvmUpperBound();
  						upperBound.setTypeReference(object);
  						((JvmWildcardTypeReference) result).getConstraints().add(0, upperBound);
  					}
  				}
  				return result;
  			}
  		};
  		@SuppressWarnings("unchecked")
  		T copy = (T) copier.copy(original);
  		copier.copyReferences();
  		return copy;
  	}
docs: Creates a deep copy of the given object and associates each copied instance with the
  clone. Does not resolve any proxies.
  
  @param original the root element to be cloned.
  @return a clone of tree rooted in original associated with the original, <code>null</code> if original is <code>null</code>.