private void CheckAndMakeMetaDataRequest(Message originalMessage, TimeSpan timeout)
        {
            var action = originalMessage.Headers.Action;

            var contractInfo = ContractInfo.FromAction(action);

            var serviceContract = TypeFinder.FindServiceContract(contractInfo.ServiceContractName);

            var paramTypes = TypeFinder.GetContractParamTypes(serviceContract, contractInfo.OperationContractName,
                                                              contractInfo.Action);

            var store = ObjectBuilder.GetModelStore();

            var metaDataRequired = paramTypes.Any(paramType => store.GetModel(paramType.Type, ModeType.Wcf) == null);

            if (!metaDataRequired)
            {
                return;
            }

            var metadataRequestMessage = GetMetaDataRequestMessage(action);

            var metaDataReply = _innerChannel.Request(metadataRequestMessage);

            if (metaDataReply == null)
            {
                throw new FaultException(
                          string.Format(
                              "The service at {0} could not be contacted to get the necessary metadata, make sure the server is available.",
                              RemoteAddress.Uri.ToString()
                              ));
            }

            var headers = metaDataReply.Headers;

            var serializer    = ObjectBuilder.GetSerializer();
            var modelProvider = ObjectBuilder.GetModelProvider();

            foreach (var messageHeader in headers)
            {
                if (messageHeader.Name.StartsWith(Constants.MetaDataHeaderKeySuffix))
                {
                    var contractNamespace = messageHeader.Name.Replace(Constants.MetaDataHeaderKeySuffix, string.Empty);

                    var contractType = TypeFinder.FindDataContract(contractNamespace, contractInfo.ServiceContractName,
                                                                   contractInfo.Action);

                    var contractMetaDataString = headers.GetHeader <string>(messageHeader.Name, messageHeader.Namespace);

                    var contractMeta = BinaryConverter.FromString(contractMetaDataString);

                    var metaData = serializer.Deserialize <TypeMetaData>(contractMeta, ModeType.Wcf);

                    modelProvider.CreateModelInfo(contractType, metaData, ModeType.Wcf);
                }
            }
        }