Final fix for Bug 318084 -  [compiler] cannot callin-bind a callout-defined method

diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/control/Dependencies.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/control/Dependencies.java
index bae7ee5..f90165a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/control/Dependencies.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/control/Dependencies.java
@@ -1644,8 +1644,10 @@
 		StandardElementGenerator.createGetBaseForUnboundLowerable(clazz);
         
 		// 6. resolve method mappings and create callout methods:
-		resolveMethodMappings(clazz);
+		MethodMappingResolver resolver = resolveCalloutMappings(clazz);
 		CalloutImplementor.transformCallouts(clazz);
+		if (resolver != null)
+			resolver.resolve(false/*doCallout*/); // callins last so all methods incl. callout are already in place
 
         clazz.setState(STATE_METHODS_CREATED);
         return true;
@@ -1730,7 +1732,7 @@
 	}
 
 	// detail of STATE_METHODS_CREATED:
-	private static void resolveMethodMappings(RoleModel role) 
+	private static MethodMappingResolver resolveCalloutMappings(RoleModel role) 
 	{
 		ReferenceBinding roleBinding = role.getBinding();
 
@@ -1761,9 +1763,11 @@
 			
 			// actually need to proceed even with no base class, because
 			// method mappings without baseclass are reported within resolve() below:
-			MethodMappingResolver resolver = new MethodMappingResolver(role);
-			resolver.resolve(!hasBaseclassProblem && needMethodBodies(roleDecl));
+			MethodMappingResolver resolver = new MethodMappingResolver(role, !hasBaseclassProblem && needMethodBodies(roleDecl));
+			resolver.resolve(true/*doCallout*/);
+			return resolver; // pass this resolver so establishMethodsCreated can continue with resolving callins
 		}
+		return null;
 	}
 
 
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/mappings/CalloutImplementor.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/mappings/CalloutImplementor.java
index 211f6e2..e174c7d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/mappings/CalloutImplementor.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/mappings/CalloutImplementor.java
@@ -374,7 +374,7 @@
     	if (calloutBindingDeclaration.binding.inferred == InferenceKind.NONE) { // don't advertise inferred callout via the interface.
     		if (templateBinding.isStatic())		 // no real ifc part for static method, fake it! 
 	    		createInterfaceFakeStatic(templateBinding, calloutBindingDeclaration);
-    		else if (!overridesExplicitNonRole)  // also no ifc part for method from explicit non-role super
+    		else if (((modifiers & AccPrivate) == 0) && !overridesExplicitNonRole)  // also no ifc part for privates and methods from explicit non-role super
 			    createAbstractRoleMethodDeclarationPart(templateBinding,
 				    calloutBindingDeclaration,
 				    modifiers,
@@ -458,10 +458,13 @@
 		}
 		else // == CLASS
 		{
-			if (calloutBindingDeclaration.binding.inferred == InferenceKind.NONE) { // only if actually advertised in the ifc-part
+			if ((modifiers & AccPrivate) != 0) { // don't advertize in ifc
+				// FIXME(SH): need to generate bridge methdods?
+			} else if (calloutBindingDeclaration.binding.inferred == InferenceKind.NONE) { // only if actually advertised in the ifc-part
 				// generated callout method must be public in the classPart.
 				// access control is done only via the interface part.
-				newMethod.modifiers &= ~(AccProtected | AccPrivate);
+				MethodModel.getModel(newMethod).storeModifiers(newMethod.modifiers);
+				newMethod.modifiers &= ~(AccProtected);
 				newMethod.modifiers |= AccPublic;
 			}
 			// abstract will be cleared once we are done.
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/mappings/MethodMappingResolver.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/mappings/MethodMappingResolver.java
index deb2227..3f340eb 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/mappings/MethodMappingResolver.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/mappings/MethodMappingResolver.java
@@ -53,21 +53,22 @@
 	/** Index is the methods name+signature */
 	private Map<String, List<CalloutMappingDeclaration>> _foundRoleMethods
 							= new HashMap<String, List<CalloutMappingDeclaration>>();
-
+	boolean resolveBaseMethods;
 
 	/**
 	 * @param role
 	 */
-	public MethodMappingResolver(RoleModel role)
+	public MethodMappingResolver(RoleModel role, boolean resolveBaseMethods)
 	{
 		this._role      = role;
 		this._roleScope = role.getAst().scope; // we definitely have an AST here
+		this.resolveBaseMethods = resolveBaseMethods;
 	}
 
 	/**
 	 * Main entry for STATE_MAPPINGS_RESOLVED
 	 */
-	public boolean resolve(boolean resolveBaseMethods)
+	public boolean resolve(boolean doCallout)
 	{
 		AbstractMethodMappingDeclaration[] methodMappings =
 			this._role.getAst().callinCallouts;
@@ -81,10 +82,12 @@
 		for (int idx = 0; idx < methodMappings.length; idx++)
 		{
 			AbstractMethodMappingDeclaration methodMapping = methodMappings[idx];
+			if (methodMapping.isCallout() != doCallout)
+				continue;
 			if (this._role.getBinding().baseclass() == null && !this._role.hasBaseclassProblem()) {
 				this._roleScope.problemReporter().methodMappingNotInBoundRole(methodMapping, this._role.getAst());
 				methodMapping.tagAsHavingErrors();
-				resolveBaseMethods = false;
+				this.resolveBaseMethods = false;
 			}
 
 			methodMapping.resolveAnnotations();
@@ -95,12 +98,12 @@
 					this._roleScope.problemReporter().calloutToEnclosing((CalloutMappingDeclaration)methodMapping, this._role);
 					result = false;
 				} else {
-					result &= resolveCalloutMapping((CalloutMappingDeclaration) methodMapping, resolveBaseMethods);
+					result &= resolveCalloutMapping((CalloutMappingDeclaration) methodMapping);
 				}
 			}
 			else // callin:
 			{
-				result &= resolveCallinMapping((CallinMappingDeclaration) methodMapping, resolveBaseMethods);
+				result &= resolveCallinMapping((CallinMappingDeclaration) methodMapping);
 			}
 
 		}
@@ -119,11 +122,10 @@
      * Reports as many errors as can be found.
      * @return true if no error occurred
      */
-    private boolean resolveCallinMapping(CallinMappingDeclaration callinMappingDeclaration,
-    								     boolean resolveBaseMethods)
+    private boolean resolveCallinMapping(CallinMappingDeclaration callinMappingDeclaration)
     {
 		// main resolving task:
-		callinMappingDeclaration.resolveMethodSpecs(this._role, this._role.getBaseTypeBinding(), resolveBaseMethods);
+		callinMappingDeclaration.resolveMethodSpecs(this._role, this._role.getBaseTypeBinding(), this.resolveBaseMethods);
 
 		callinMappingDeclaration.binding._roleMethodBinding = callinMappingDeclaration.getRoleMethod();
 
@@ -135,7 +137,7 @@
      * Reports as many errors as can be found.
      * @return true if no error occurred
      */
-    private boolean resolveCalloutMapping(CalloutMappingDeclaration calloutMappingDeclaration, boolean resolveBaseMethod)
+    private boolean resolveCalloutMapping(CalloutMappingDeclaration calloutMappingDeclaration)
 	{
 		if (calloutMappingDeclaration.scope == null) { // severe error
 			assert calloutMappingDeclaration.hasErrors();
@@ -146,13 +148,13 @@
 		// A callout-with-signatures should always resolve its base method,
 		// because that base method could determine the static flag.
 		calloutMappingDeclaration.resolveMethodSpecs(this._role,this._role.getBaseTypeBinding(),
-													 resolveBaseMethod||calloutMappingDeclaration.hasSignature);
+													 this.resolveBaseMethods||calloutMappingDeclaration.hasSignature);
 
 //		This binding is part of the interface part of a role:
 		MethodBinding roleMethodBinding = calloutMappingDeclaration.roleMethodSpec.resolvedMethod;
 
 		calloutMappingDeclaration.binding._roleMethodBinding = roleMethodBinding;
-		if (resolveBaseMethod) {
+		if (this.resolveBaseMethods) {
 			if (   calloutMappingDeclaration.baseMethodSpec != null
 				&& calloutMappingDeclaration.baseMethodSpec.resolvedMethod != null)
 			{