/// <summary>
        /// 
        /// </summary>
        /// 
        /// <param name="source"></param>
        /// 
        /// <returns></returns>
        /// 
        public static ExchangeResponse Assign(ExchangeDisposition source)
        {
            ExchangeResponse result = new ExchangeResponse();

            result.Status = source.Status;

            result.Guid = source.Guid;
            result.Aid = source.Aid;
            result.Cid = source.Cid;
            result.Tid = source.Tid;

            result.MatchCount = source.MatchCount;
            result.Amount = source.Amount;
            result.Errors = source.Errors.ToArray();

            return result;
        }
        /// <summary>
        /// 
        /// </summary>
        /// 
        /// <param name="lead"></param>
        /// 
        /// <returns></returns>
        /// 
        public ExchangeDisposition Allocate(Lead lead)
        {
            lock (gateways)
            {
                foreach (IPartnerGateway gateway in gateways)
                {
                    gateway.BeginPost(lead, ReduceCallback, this);
                }
            }

            signal.WaitOne(timout, false);

            ExchangeDisposition allocation = new ExchangeDisposition();
            allocation.Coverage = false;
            allocation.Responses = results;

            foreach (PartnerGatewayResponse response in results)
            {
                if (response.Coverage)
                {
                    allocation.Coverage = true;
                    break;
                }
            }

            return allocation;
        }
        /// <summary>
        /// 
        /// </summary>
        /// 
        /// <param name="lead"></param>
        /// 
        /// <returns></returns>
        /// 
        public ExchangeDisposition Execute(Lead lead)
        {
            OnExchangeServiceStart(this, new ExchangeEvent<IExchangeEngine>(this));

            Stopwatch timer = new Stopwatch();
            timer.Start();

            ExchangeRuntime runtime = CreateRuntime();
            runtime.Active = true;
            runtime.StoreData(ExchangeRuntime.LEAD, lead);
            runtime.Vertical = "DEBT";
            runtime.VerticalType = "DATA";
            runtime.LeadSource = LeadSource.WS;

            try
            {
                runtime.Invoke();
            }
            catch (Exception exception)
            {
                ExceptionHandler<ServiceExceptionFactory>.Process(exception, true, "Failed to save outbound duplicate entity: {0}.", typeof(OutboundDuplicate));

                ExchangeDisposition error = new ExchangeDisposition();
                error.Aid = lead.Aid;
                error.Cid = lead.Cid;
                error.Tid = lead.Tid;
                error.Status = ExchangeRuntime.ERROR;
                error.Time = DateTime.Now;
                error.Guid = lead.Guid;
                error.Amount = 0;
                error.MatchCount = 0;
                return error;
            }

            timer.Stop();

            // Audit Trail
            // runtime.AllocationAuditTrail.TotalElapsedTime = timer.ElapsedMilliseconds;
            runtime.FlagComplete();

            OnExchangeServiceEnd(this, new ExchangeEvent<IExchangeEngine>(this));

            if (runtime.ValidationErrors.Count > 0)
            {
                ExchangeDisposition error = new ExchangeDisposition();
                error.Aid = lead.Aid;
                error.Cid = lead.Cid;
                error.Tid = lead.Tid;
                error.Status = ExchangeRuntime.INVALID;
                error.Time = DateTime.Now;
                error.Guid = lead.Guid;
                error.Amount = 0;
                error.MatchCount = 0;
                error.Errors = runtime.ValidationErrors;

                return error;
            }

            if (runtime.Errors.Count > 0)
            {
                ExchangeDisposition error = new ExchangeDisposition();
                error.Aid = lead.Aid;
                error.Cid = lead.Cid;
                error.Tid = lead.Tid;
                error.Status = ExchangeRuntime.ERROR;
                error.Time = DateTime.Now;
                error.Guid = lead.Guid;
                error.Amount = 0;
                error.MatchCount = 0;
                return error;
            }

            if (runtime.IsInboundDuplicate)
            {
                ExchangeDisposition duplicate = new ExchangeDisposition();
                duplicate.Aid = lead.Aid;
                duplicate.Cid = lead.Cid;
                duplicate.Tid = lead.Tid;
                duplicate.Status = ExchangeRuntime.DUPLICATE;
                duplicate.Time = DateTime.Now;
                duplicate.Guid = lead.Guid;
                duplicate.Amount = 0;
                duplicate.MatchCount = 0;
                return duplicate;
            }

            if (runtime.IsSuspect)
            {
                ExchangeDisposition suspect = new ExchangeDisposition();
                suspect.Aid = lead.Aid;
                suspect.Cid = lead.Cid;
                suspect.Tid = lead.Tid;
                suspect.Status = ExchangeRuntime.PENDING_VERIFICATION;
                suspect.Time = DateTime.Now;
                suspect.Guid = lead.Guid;
                suspect.Amount = 0;
                suspect.MatchCount = 0;
                return suspect;
            }

            if (runtime.PendingMatch)
            {
                ExchangeDisposition pendingMatch = new ExchangeDisposition();
                pendingMatch.Aid = lead.Aid;
                pendingMatch.Cid = lead.Cid;
                pendingMatch.Tid = lead.Tid;
                pendingMatch.Status = ExchangeRuntime.PENDING_MATCH;
                pendingMatch.Time = DateTime.Now;
                pendingMatch.Guid = lead.Guid;
                pendingMatch.Amount = 0;
                pendingMatch.MatchCount = 0;
                return pendingMatch;
            }

            ExchangeDisposition disposition = new ExchangeDisposition();
            disposition.Aid = lead.Aid;
            disposition.Amount = 0.00;
            disposition.Cid = lead.Cid;
            disposition.Tid = lead.Tid;
            disposition.Status = ExchangeRuntime.ACCEPTED;
            disposition.Time = DateTime.Now;
            disposition.Guid = lead.Guid;
            disposition.MatchCount = runtime.AllocationCount;

            return disposition;
        }