Improve analysis of base-calls in the presence of inheritance:
* use sorted array of member types for analyseCode so we know in time
  whether a super-call triggers a base-call.
* include super message sends in base-call analysis.
Fixes new tests test4516_inheritedBaseCall2-5
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
index c9e1dc0..a24cab3 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
@@ -14,6 +14,9 @@
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.ast;
 
+import static org.eclipse.objectteams.otdt.core.compiler.IOTConstants.CALLIN_FLAG_DEFINITELY_MISSING_BASECALL;
+import static org.eclipse.objectteams.otdt.core.compiler.IOTConstants.CALLIN_FLAG_POTENTIALLY_MISSING_BASECALL;
+
 import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.internal.compiler.ASTVisitor;
 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
@@ -28,6 +31,7 @@
 import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
 import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
 import org.eclipse.jdt.internal.compiler.lookup.InvocationSite;
+import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
 import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
 import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
 import org.eclipse.jdt.internal.compiler.lookup.MissingTypeBinding;
@@ -161,8 +165,47 @@
 		//               NullReferenceTest#test0510
 	}
 	manageSyntheticAccessIfNecessary(currentScope, flowInfo);
+//{ObjectTeams: base calls via super:
+	flowInfo = checkBaseCallsIfSuper(currentScope, flowInfo);
+// SH}
 	return flowInfo;
 }
+//{ObjectTeams: checkBaseCallsIfSuper
+protected FlowInfo checkBaseCallsIfSuper(BlockScope currentScope, FlowInfo flowInfo) {
+	MethodScope methodScope = currentScope.methodScope();
+	if (methodScope == null) 
+		return flowInfo;
+	AbstractMethodDeclaration methodDecl = methodScope.referenceMethod();
+	if (methodDecl == null || !methodDecl.isCallin()) 
+		return flowInfo;
+	if (!this.isSuperAccess())
+		return flowInfo;
+	MethodDeclaration callinMethod = (MethodDeclaration) methodDecl;
+	if (MethodModel.hasCallinFlag(this.binding, CALLIN_FLAG_DEFINITELY_MISSING_BASECALL))
+		return flowInfo; // no effect
+	
+	boolean definitelyViaSuper = !MethodModel.hasCallinFlag(this.binding, CALLIN_FLAG_POTENTIALLY_MISSING_BASECALL);
+		
+	LocalVariableBinding trackingVariable = callinMethod.baseCallTrackingVariable.binding;
+	if (flowInfo.isDefinitelyAssigned(callinMethod.baseCallTrackingVariable)) {
+		if (definitelyViaSuper)
+			currentScope.problemReporter().definitelyDuplicateBasecall(this);
+		else
+			currentScope.problemReporter().potentiallyDuplicateBasecall(this);
+	} else if (flowInfo.isPotentiallyAssigned(trackingVariable)) {
+		currentScope.problemReporter().potentiallyDuplicateBasecall(this);
+	} else {
+		if (definitelyViaSuper) {
+			flowInfo.markAsDefinitelyAssigned(trackingVariable);
+		} else {
+			FlowInfo potential = flowInfo.copy();
+			potential.markAsDefinitelyAssigned(trackingVariable);
+			flowInfo = FlowInfo.conditional(flowInfo.initsWhenTrue(), potential.initsWhenTrue());
+		}
+	}
+	return flowInfo;
+}
+// SH}
 /**
  * @see org.eclipse.jdt.internal.compiler.ast.Expression#computeConversion(org.eclipse.jdt.internal.compiler.lookup.Scope, org.eclipse.jdt.internal.compiler.lookup.TypeBinding, org.eclipse.jdt.internal.compiler.lookup.TypeBinding)
  */
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
index bbcd18e..79b8b11 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
@@ -49,6 +49,7 @@
 import org.eclipse.objectteams.otdt.internal.core.compiler.smap.TeamSmapGenerator;
 import org.eclipse.objectteams.otdt.internal.core.compiler.statemachine.copyinheritance.CopyInheritance;
 import org.eclipse.objectteams.otdt.internal.core.compiler.statemachine.transformer.RoleSplitter;
+import org.eclipse.objectteams.otdt.internal.core.compiler.util.Sorting;
 
 /**
  * OTDT changes:
@@ -1205,6 +1206,8 @@
 		// type value parameters are non static fields, which are a-priori assigned.
 		nonStaticFieldInfo = TypeValueParameter.analyseCode(this.typeParameters, this.initializerScope, flowContext, nonStaticFieldInfo);
 	}
+	// analyse member types in topological order (super before sub):
+	Sorting.sortMemberTypes(this);
 // SH}
 	if (this.memberTypes != null) {
 		for (int i = 0, count = this.memberTypes.length; i < count; i++) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/util/Sorting.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/util/Sorting.java
index e4ed17a..033d245 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/util/Sorting.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/util/Sorting.java
@@ -16,6 +16,7 @@
  **********************************************************************/
 package org.eclipse.objectteams.otdt.internal.core.compiler.util;
 
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
 import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
 import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
@@ -152,4 +153,28 @@
 		}
 		return o;
 	}
+	
+	/** Apply the sorting from member type bindings to their ASTs, too. */
+	public static void sortMemberTypes(TypeDeclaration typeDeclaration) {
+		if (typeDeclaration.memberTypes == null) return;
+		ReferenceBinding[] bindings = typeDeclaration.binding.memberTypes;
+		TypeDeclaration[] unsorted = typeDeclaration.memberTypes;
+		TypeDeclaration[] newMembers = new TypeDeclaration[unsorted.length];
+		int k = unsorted.length-1;
+		allMembers: for (int i=0; i<unsorted.length; i++) {
+			ReferenceBinding current = unsorted[i].binding;
+			if (current != null) {
+				// find insertion point from sorted bindings:
+				for (int j=0; j<bindings.length; j++) {
+					if (bindings[j] == current) {
+						newMembers[j] = unsorted[i];
+						continue allMembers;
+					}
+				}
+			}
+			// emergency, so we'll never lose any member types:
+			newMembers[k--] = unsorted[i];
+		}
+		typeDeclaration.memberTypes = newMembers;
+	}
 }