/// <summary>
        /// Initialized Transaction.
        /// </summary>
        /// <param name="ParamList">Parameter List</param>
        /// <param name="RequestId">Request Id</param>
        public void InitTrans(String ParamList, String RequestId)
        {
            Logger.Instance.Log("PayPal.Payments.Communication.PaymentStateMachine.InitTrans(String): Entered.",
                                PayflowConstants.SEVERITY_DEBUG);

            try
            {
                this.mConnection.RequestId = RequestId;
                this.mPaymentState         = new SendInitState(this.mConnection, ParamList, ref psmContext);
            }
            catch (Exception Ex)
            {
                ErrorObject Err = PayflowUtility.PopulateCommError(PayflowConstants.E_CONTXT_INIT_FAILED, Ex,
                                                                   PayflowConstants.SEVERITY_ERROR, mPaymentState.IsXmlPayRequest,
                                                                   null);
                if (!PsmContext.IsCommunicationErrorContained(Err))
                {
                    PsmContext.AddError(Err);
                }
            }
            finally
            {
                Logger.Instance.Log("PayPal.Payments.Communication.PaymentStateMachine.InitTrans(String): Exiting.",
                                    PayflowConstants.SEVERITY_DEBUG);
            }
        }
        /// <summary>
        /// Initializes transaction context.
        /// </summary>
        /// <param name="HostAddress">Payflow Host Address.</param>
        /// <param name="HostPort">Payflow Host Port.</param>
        /// <param name="TimeOut">Transaction timeout.</param>
        /// <param name="ProxyAddress">Proxy Address.</param>
        /// <param name="ProxyPort">Proxy Port.</param>
        /// <param name="ProxyLogon">Proxy Logon Id.</param>
        /// <param name="ProxyPassword">Proxy Password.</param>
        /// <param name="ClientInfo">Client Info</param>
        public void InitializeContext(String HostAddress, int HostPort, int TimeOut, String ProxyAddress, int ProxyPort, String ProxyLogon, String ProxyPassword, ClientInfo ClientInfo)
        {
            Logger.Instance.Log("PayPal.Payments.Communication.PaymentStateMachine.InitializeContext(String, int, int, String, int, String, String): Entered.",
                                PayflowConstants.SEVERITY_DEBUG);
            try
            {
                this.mConnection.InitializeConnection(HostAddress, HostPort, TimeOut, ProxyAddress, ProxyPort, ProxyLogon, ProxyPassword);
                if (ClientInfo != null)
                {
                    mClientInfo = ClientInfo;
                }
                else
                {
                    mClientInfo = new ClientInfo();
                }

                this.SetVersionTracking();
                this.mConnection.ClientInfo = mClientInfo;
            }
            catch (Exception Ex)
            {
                ErrorObject Err = PayflowUtility.PopulateCommError(PayflowConstants.E_EMPTY_PARAM_LIST, Ex,
                                                                   PayflowConstants.SEVERITY_ERROR, mPaymentState.IsXmlPayRequest,
                                                                   null);
                if (!PsmContext.IsCommunicationErrorContained(Err))
                {
                    PsmContext.AddError(Err);
                }
            }
            finally
            {
                Logger.Instance.Log("PayPal.Payments.Communication.PaymentStateMachine.InitializeContext(String,int,int,String, nt,String,String): Exiting.",
                                    PayflowConstants.SEVERITY_DEBUG);
            }
        }
        /// <summary>
        /// Executes the transaction.
        /// </summary>
        public void Execute()
        {
            Logger.Instance.Log("PayPal.Payments.Communication.PaymentStateMachine.Execute(): Entered.",
                                PayflowConstants.SEVERITY_DEBUG);

            try
            {
                if (PsmContext.HighestErrorLvl == PayflowConstants.SEVERITY_FATAL)
                {
                    String TrxResponse = mPaymentState.TransactionResponse;
                    String Message;
                    if (TrxResponse != null && TrxResponse.Length > 0)
                    {
                        Message = TrxResponse;
                    }
                    else
                    {
                        ArrayList   ErrorList       = psmContext.GetErrors(PayflowConstants.SEVERITY_FATAL);
                        ErrorObject FirstFatalError = (ErrorObject)ErrorList[0];
                        Message = FirstFatalError.ToString();
                    }
                    mPaymentState.SetTransactionFail = Message;
                }
                else
                {
                    Logger.Instance.Log("PayPal.Payments.Communication.PaymentStateMachine.Execute(): Current State = " + mPaymentState,
                                        PayflowConstants.SEVERITY_DEBUG);
                    mPaymentState.Execute();
                }
            }
            catch (Exception Ex)
            {
                ErrorObject Err = PayflowUtility.PopulateCommError(PayflowConstants.E_UNKNOWN_STATE, Ex, PayflowConstants.SEVERITY_ERROR,
                                                                   mPaymentState.IsXmlPayRequest,
                                                                   null);
                if (!PsmContext.IsCommunicationErrorContained(Err))
                {
                    PsmContext.AddError(Err);
                }
            }
            finally
            {
                // perform state transition
                mPaymentState = GetNextState(mPaymentState);
                mClientInfo   = mConnection.ClientInfo;
                Logger.Instance.Log("PayPal.Payments.Communication.PaymentStateMachine.Execute(): Exiting.  Current State = " + mPaymentState.GetType().ToString(),
                                    PayflowConstants.SEVERITY_DEBUG);
            }
        }
        /// <summary>
        /// Changes the Payment States depending upon
        /// the current state status.
        /// </summary>
        /// <param name="CurrentPmtState">Current Payment State.</param>
        /// <returns>Next Payment State</returns>
        private PaymentState GetNextState(PaymentState CurrentPmtState)
        {
            Logger.Instance.Log("PayPal.Payments.Communication.PaymentStateMachine.GetNextState(PaymentState): Entered.",
                                PayflowConstants.SEVERITY_DEBUG);

            if (CurrentPmtState.Success && CurrentPmtState.InProgress)
            {
                if (CurrentPmtState is TransactionReceiveState)
                {
                    // exit state
                    CurrentPmtState.SetTransactionSuccess();
                }
                else if (CurrentPmtState is SendInitState)
                {
                    Logger.Instance.Log("PayPal.Payments.Communication.PaymentStateMachine.GetNextState(PaymentState.Success): SentInitState Entered.",
                                        PayflowConstants.SEVERITY_DEBUG);

                    CurrentPmtState = new TransactionSendState(CurrentPmtState);
                }
                else if (CurrentPmtState is TransactionSendState)
                {
                    Logger.Instance.Log("PayPal.Payments.Communication.PaymentStateMachine.GetNextState(PaymentState.Success): TransactionSentState Entered.",
                                        PayflowConstants.SEVERITY_DEBUG);
                    CurrentPmtState = new TransactionReceiveState(CurrentPmtState);
                }
                else if (CurrentPmtState is SendRetryState)
                {
                    Logger.Instance.Log("PayPal.Payments.Communication.PaymentStateMachine.GetNextState(PaymentState.Success): SendRetryState Entered.",
                                        PayflowConstants.SEVERITY_DEBUG);
                    CurrentPmtState = new SendReconnectState(CurrentPmtState);
                }
                else if (CurrentPmtState is SendReconnectState)
                {
                    Logger.Instance.Log("PayPal.Payments.Communication.PaymentStateMachine.GetNextState(PaymentState.Success): SendReconnectState Entered.",
                                        PayflowConstants.SEVERITY_DEBUG);
                    CurrentPmtState = new SendInitState(CurrentPmtState);
                }
                // unknown state
                else
                {
                    String      AddlMessage = "Unknown State, Current State = " + mPaymentState.ToString();
                    ErrorObject Err         = PayflowUtility.PopulateCommError(PayflowConstants.E_UNKNOWN_STATE, null,
                                                                               PayflowConstants.SEVERITY_FATAL, mPaymentState.IsXmlPayRequest,
                                                                               AddlMessage);
                    if (!PsmContext.IsCommunicationErrorContained(Err))
                    {
                        PsmContext.AddError(Err);
                    }
                }
            }
            else if (CurrentPmtState.Failed && CurrentPmtState.InProgress)
            {
                Logger.Instance.Log("PayPal.Payments.Communication.PaymentStateMachine.GetNextState(PaymentState): Current Payment State Failed.  Current State = " + mPaymentState.ToString(),
                                    PayflowConstants.SEVERITY_DEBUG);
                if (CurrentPmtState is ReconnectState)
                {
                    // exit state
                    if (!PsmContext.IsErrorContained())
                    {
                        String      AddlMessage = "Exceeded Reconnect attempts, check context for error, Current reconnect attempt = " + mPaymentState.AttemptNo.ToString();
                        ErrorObject Err         = PayflowUtility.PopulateCommError(PayflowConstants.E_TIMEOUT_WAIT_RESP, null,
                                                                                   PayflowConstants.SEVERITY_FATAL, mPaymentState.IsXmlPayRequest,
                                                                                   AddlMessage);
                        if (!PsmContext.IsCommunicationErrorContained(Err))
                        {
                            PsmContext.AddError(Err);
                        }
                    }
                    else
                    {
                        ArrayList ErrList = new ArrayList();
                        ErrList.AddRange(PsmContext.GetErrors());
                        int HighestSevLevel = PsmContext.HighestErrorLvl;

                        int ErrorListIndex;
                        int ErrorListSize = ErrList.Count;
                        for (ErrorListIndex = 0; ErrorListIndex < ErrorListSize; ErrorListIndex++)
                        {
                            ErrorObject Err = (ErrorObject)ErrList[ErrorListIndex];
                            if (Err.SeverityLevel == HighestSevLevel)
                            {
                                int      index;
                                int      size          = Err.MessageParams.Count;
                                string[] MsgCodeParams = new string[size];
                                for (index = 0; index < size; index++)
                                {
                                    MsgCodeParams[index] = (string)Err.MessageParams[index];
                                }

                                ErrorObject Error = new ErrorObject(PayflowConstants.SEVERITY_FATAL, Err.MessageCode, MsgCodeParams);
                                ErrList[ErrorListIndex] = Error;
                                break;
                            }
                        }

                        PsmContext.ClearErrors();
                        PsmContext.AddErrors(ErrList);
                    }
                }
                else if (CurrentPmtState is SendInitState)
                {
                    Logger.Instance.Log("PayPal.Payments.Communication.PaymentStateMachine.GetNextState(PaymentState.Failed): SendInitState Entered.",
                                        PayflowConstants.SEVERITY_DEBUG);
                    CurrentPmtState = new SendReconnectState(CurrentPmtState);
                }
                else if (CurrentPmtState is TransactionSendState)
                {
                    Logger.Instance.Log("PayPal.Payments.Communication.PaymentStateMachine.GetNextState(PaymentState.Failed): TransactionSendState Entered.",
                                        PayflowConstants.SEVERITY_DEBUG);
                    CurrentPmtState = new SendRetryState(CurrentPmtState);
                }
                else if (CurrentPmtState is TransactionReceiveState)
                {
                    Logger.Instance.Log("PayPal.Payments.Communication.PaymentStateMachine.GetNextState(PaymentState.Failed): TransactionReceiveState Entered.",
                                        PayflowConstants.SEVERITY_DEBUG);
                    CurrentPmtState = new SendRetryState(CurrentPmtState);
                }
                // unknown state
                else
                {
                    String      AddlMessage = "Current State = " + mPaymentState.ToString();
                    ErrorObject Err         = PayflowUtility.PopulateCommError(PayflowConstants.E_UNKNOWN_STATE, null,
                                                                               PayflowConstants.SEVERITY_FATAL, mPaymentState.
                                                                               IsXmlPayRequest, AddlMessage);
                    if (!PsmContext.IsCommunicationErrorContained(Err))
                    {
                        PsmContext.AddError(Err);
                    }
                }
            }

            Logger.Instance.Log("PayPal.Payments.Communication.PaymentStateMachine.GetNextState(PaymentState): Obtained State = "
                                + mPaymentState.GetType().ToString(),
                                PayflowConstants.SEVERITY_INFO);
            Logger.Instance.Log("PayPal.Payments.Communication.PaymentStateMachine.GetNextState(PaymentState): Exiting.",
                                PayflowConstants.SEVERITY_DEBUG);
            return(CurrentPmtState);
        }