private async Task CreateAndSendCallMessageAsync(AnalysisInvocationExpession callInfo, 
                            MethodDescriptor realCallee, TypeDescriptor receiverType, PropagationKind propKind)
		{
			var callMessage = await CreateCallMessageAsync(callInfo, realCallee, receiverType, propKind);
			var callerMessage = new CallerMessage(this.EntityDescriptor, callMessage);
			var destination = EntityFactory.Create(realCallee, this.dispatcher);

			await this.SendMessageAsync(destination, callerMessage);
		}
        //public void RegisterVirtualDelegateCall(MethodDescriptor callee, VariableNode receiver,
        //                                    IList<AnalysisNode> arguments,
        //                                    VariableNode lhs, DelegateVariableNode delegateVariableNode)
        //{
        //    Contract.Requires(receiver != null);
        //    Contract.Requires(arguments != null);
        //    Contract.Requires(lhs != null);
        //    Contract.Requires(callee != null);
        //    Contract.Requires(delegateVariableNode != null);
        //    var callExp = new DelegateCallInfo(this.Method, delegateVariableNode, receiver, arguments, lhs);
        //    this.PropagationGraph.AddEdge(receiver, delegateVariableNode);
        //    RegisterInvocation(arguments, delegateVariableNode, callExp);
        //}
        private void RegisterInvocation(IList<PropGraphNodeDescriptor> arguments, AnalysisCallNode invocationNode, 
            AnalysisInvocationExpession callExp)
        {
            Contract.Requires(callExp != null);
            Contract.Requires(arguments != null);
            Contract.Requires(invocationNode != null);

            this.PropagationGraph.AddCall(callExp, invocationNode);
            this.PropagationGraph.AddToWorkList(invocationNode);

            foreach (var a in arguments)
            {
                if (a != null)
                {
                    PropagationGraph.AddEdge(a, invocationNode);
                }
            }
        }
        private async Task<CallMessageInfo> CreateCallMessageAsync(AnalysisInvocationExpession callInfo,
                                                            MethodDescriptor actuallCallee,
                                                            TypeDescriptor computedReceiverType,
                                                            PropagationKind propKind)
        {
            // var calleType = (TypeDescriptor)actuallCallee.ContainerType;
            var calleType = computedReceiverType;
            ISet<TypeDescriptor> potentialReceivers = new HashSet<TypeDescriptor>();

            if (callInfo.Receiver != null)
            {
                // BUG!!!! I should use simply computedReceiverType
                // Instead of copying all types with use the type we use to compute the callee
                foreach (var type in GetTypes(callInfo.Receiver, propKind))
                {
                    var isSubType = await codeProvider.IsSubtypeAsync(type, calleType);

                    if(isSubType)
                    {
                        potentialReceivers.Add(type);
                    }
                }
                //potentialReceivers.UnionWith(
                //        GetTypes(callInfo.Receiver, propKind)
                //        .Where(t => codeProvider.IsSubtype(t, calleType)));
                //.Where(t => t.IsSubtype(calleType)));

                // potentialReceivers.Add((AnalysisType)calleType);
            }

            var argumentValues = callInfo.Arguments
                .Select(a => a != null ?
                GetTypes(a, propKind) :
                new HashSet<TypeDescriptor>());

            Contract.Assert(argumentValues.Count() == callInfo.Arguments.Count());

            return new CallMessageInfo(callInfo.Caller, actuallCallee, callInfo.CallNode,
                                                potentialReceivers, new List<ISet<TypeDescriptor>>(argumentValues),
                                                callInfo.LHS, callInfo.InstatiatedTypes, propKind);
        }
        private void CreateAndSendCallMessage(AnalysisInvocationExpession callInfo, MethodDescriptor realCallee, 
            TypeDescriptor receiverType, PropagationKind propKind)
        {
            /// Here I have all the necessary info to update the callgraph
            ///
            var callMessage = CreateCallMessage(callInfo, realCallee, receiverType, propKind);
            var callerMessage = new CallerMessage(this.EntityDescriptor, callMessage);
            var destination = EntityFactory.Create(realCallee, this.dispatcher);

            this.SendMessage(destination, callerMessage);
        }