protected LightweightTypeReference computeForLoopParameterType(final XForLoopExpression object,
			final ITypeComputationState state) {
		JvmFormalParameter declaredParam = object.getDeclaredParam();
		LightweightTypeReference parameterType = getDeclaredParameterType(declaredParam, state);
		final JvmGenericType iterableType = findDeclaredType(Iterable.class, state.getReferenceOwner());
		
		if (parameterType != null && !parameterType.isPrimitiveVoid()) {
			final CompoundTypeReference withSynonyms = state.getReferenceOwner().newCompoundTypeReference(true);
			LightweightTypeReference iterableOrArray = getAndEnhanceIterableOrArrayFromComponent(parameterType, iterableType, withSynonyms);
			
			ITypeComputationState iterableState = state.withExpectation(withSynonyms);
			ITypeComputationResult forExpressionResult = iterableState.computeTypes(object.getForExpression());
			LightweightTypeReference forExpressionType = forExpressionResult.getActualExpressionType();
			if (forExpressionType!= null) {
				if (forExpressionType.isAny() || forExpressionType.isUnknown()) {
					iterableState.refineExpectedType(object.getForExpression(), iterableOrArray);
				} else if (forExpressionType.isResolved()) {
					int assignability = iterableOrArray.internalIsAssignableFrom(forExpressionType, TypeConformanceComputationArgument.DEFAULT);
					if ((assignability & ConformanceFlags.SUCCESS) != 0 && (assignability & ConformanceFlags.RAW_TYPE_CONVERSION) == 0)
						iterableState.refineExpectedType(object.getForExpression(), forExpressionType);
					else {
						ArrayTypeReference array = forExpressionType.tryConvertToArray();
						if (array != null) {
							LightweightTypeReference arrayComponentType = array.getComponentType();
							if (parameterType.isAssignableFrom(arrayComponentType)) {
								iterableState.refineExpectedType(object.getForExpression(), forExpressionType);
							} else {
								LightweightTypeReference rawArrayComponentType = arrayComponentType.getRawTypeReference();
								AbstractDiagnostic diagnostic = new EObjectDiagnosticImpl(
										Severity.ERROR, 
										IssueCodes.INCOMPATIBLE_TYPES, 
										String.format("Type mismatch: cannot convert from element type %s to %s", rawArrayComponentType.getHumanReadableName(), parameterType.getHumanReadableName()), 
										object, 
										XbasePackage.Literals.XFOR_LOOP_EXPRESSION__FOR_EXPRESSION, -1, null);
								state.addDiagnostic(diagnostic);
							}
						}
					}
				}
			}
		} else {
			ITypeReferenceOwner owner = state.getReferenceOwner();
			LightweightTypeReference iterable = null;
			if (iterableType == null) {
				iterable = owner.newUnknownTypeReference(Iterable.class.getName());
			} else {
				WildcardTypeReference wildcard = owner.newWildcardTypeReference();
				ParameterizedTypeReference iterableTypeRef = owner.newParameterizedTypeReference(iterableType);
				UnboundTypeReference unbound = state.createUnboundTypeReference(object, iterableType.getTypeParameters().get(0));
				wildcard.addUpperBound(unbound);
				iterableTypeRef.addTypeArgument(wildcard);
				iterable = iterableTypeRef;
				// TODO do we have to add synonyms, too?
			}
			ITypeComputationState iterableState = state.withExpectation(iterable); 
			ITypeComputationResult forExpressionResult = iterableState.computeTypes(object.getForExpression());
			LightweightTypeReference forExpressionType = forExpressionResult.getActualExpressionType();
			if (forExpressionType != null) {
				if (!forExpressionType.isAny() && (iterable.isAssignableFrom(forExpressionType) || forExpressionType.isArray())) {
					iterableState.refineExpectedType(object.getForExpression(), forExpressionType);
				}
				parameterType = getElementOrComponentType(forExpressionType, state.getReferenceOwner());
			}
		}
		return parameterType;
	}
protected LightweightTypeReference computeForLoopParameterType ( final XForLoopExpression object , final ITypeComputationState state ) { JvmFormalParameter declaredParam = object . getDeclaredParam ( ) ; LightweightTypeReference parameterType = getDeclaredParameterType ( declaredParam , state ) ; final JvmGenericType iterableType = findDeclaredType ( Iterable . class , state . getReferenceOwner ( ) ) ; if ( parameterType != null && ! parameterType . isPrimitiveVoid ( ) ) { final CompoundTypeReference withSynonyms = state . getReferenceOwner ( ) . newCompoundTypeReference ( true ) ; LightweightTypeReference iterableOrArray = getAndEnhanceIterableOrArrayFromComponent ( parameterType , iterableType , withSynonyms ) ; ITypeComputationState iterableState = state . withExpectation ( withSynonyms ) ; ITypeComputationResult forExpressionResult = iterableState . computeTypes ( object . getForExpression ( ) ) ; LightweightTypeReference forExpressionType = forExpressionResult . getActualExpressionType ( ) ; if ( forExpressionType != null ) { if ( forExpressionType . isAny ( ) || forExpressionType . isUnknown ( ) ) { iterableState . refineExpectedType ( object . getForExpression ( ) , iterableOrArray ) ; } else if ( forExpressionType . isResolved ( ) ) { int assignability = iterableOrArray . internalIsAssignableFrom ( forExpressionType , TypeConformanceComputationArgument . DEFAULT ) ; if ( ( assignability & ConformanceFlags . SUCCESS ) != 0 && ( assignability & ConformanceFlags . RAW_TYPE_CONVERSION ) == 0 ) iterableState . refineExpectedType ( object . getForExpression ( ) , forExpressionType ) ; else { ArrayTypeReference array = forExpressionType . tryConvertToArray ( ) ; if ( array != null ) { LightweightTypeReference arrayComponentType = array . getComponentType ( ) ; if ( parameterType . isAssignableFrom ( arrayComponentType ) ) { iterableState . refineExpectedType ( object . getForExpression ( ) , forExpressionType ) ; } else { LightweightTypeReference rawArrayComponentType = arrayComponentType . getRawTypeReference ( ) ; AbstractDiagnostic diagnostic = new EObjectDiagnosticImpl ( Severity . ERROR , IssueCodes . INCOMPATIBLE_TYPES , String . format ( "Type mismatch: cannot convert from element type %s to %s" , rawArrayComponentType . getHumanReadableName ( ) , parameterType . getHumanReadableName ( ) ) , object , XbasePackage . Literals . XFOR_LOOP_EXPRESSION__FOR_EXPRESSION , - 1 , null ) ; state . addDiagnostic ( diagnostic ) ; } } } } } } else { ITypeReferenceOwner owner = state . getReferenceOwner ( ) ; LightweightTypeReference iterable = null ; if ( iterableType == null ) { iterable = owner . newUnknownTypeReference ( Iterable . class . getName ( ) ) ; } else { WildcardTypeReference wildcard = owner . newWildcardTypeReference ( ) ; ParameterizedTypeReference iterableTypeRef = owner . newParameterizedTypeReference ( iterableType ) ; UnboundTypeReference unbound = state . createUnboundTypeReference ( object , iterableType . getTypeParameters ( ) . get ( 0 ) ) ; wildcard . addUpperBound ( unbound ) ; iterableTypeRef . addTypeArgument ( wildcard ) ; iterable = iterableTypeRef ; } ITypeComputationState iterableState = state . withExpectation ( iterable ) ; ITypeComputationResult forExpressionResult = iterableState . computeTypes ( object . getForExpression ( ) ) ; LightweightTypeReference forExpressionType = forExpressionResult . getActualExpressionType ( ) ; if ( forExpressionType != null ) { if ( ! forExpressionType . isAny ( ) && ( iterable . isAssignableFrom ( forExpressionType ) || forExpressionType . isArray ( ) ) ) { iterableState . refineExpectedType ( object . getForExpression ( ) , forExpressionType ) ; } parameterType = getElementOrComponentType ( forExpressionType , state . getReferenceOwner ( ) ) ; } } return parameterType ; }
/* @Nullable