private bool consumeHold(IAssetCallback assetCallbacks, GloebitAPIWrapper.ITransactionAlert transactionAlerts, out string returnMsg)
        {
            if (this.canceled)
            {
                // Should never get a delayed consume after a cancel.  return false.
                returnMsg = "Consume: already canceled";
                return(false);
            }
            if (!this.enacted)
            {
                // Should never get a consume before we've enacted.  return false.
                returnMsg = "Consume: Not yet enacted";
                return(false);
            }
            if (this.consumed)
            {
                // already consumed. return true.
                returnMsg = "Cosume: Already consumed";
                return(true);
            }

            // First reception of consume for asset.
            // Send alert that CONSUME_GLOEBIT has completed
            transactionAlerts.AlertTransactionStageCompleted(this, GloebitAPI.TransactionStage.CONSUME_GLOEBIT, String.Empty);
            // Do specific consume functionality for the Asset / local transaction part
            this.consumed = assetCallbacks.processAssetConsumeHold(this, out returnMsg);
            if (this.consumed)
            {
                this.finishedTime = DateTime.UtcNow;
                GloebitTransactionData.Instance.Store(this);

                // send alert that CONSUME_ASSET has completed
                // TODO: should we pass the returnMsg instead of String.Empty, or is this always empty on success? -- investigate
                transactionAlerts.AlertTransactionStageCompleted(this, GloebitAPI.TransactionStage.CONSUME_ASSET, String.Empty);
                // transaction officially complete at this point
                transactionAlerts.AlertTransactionSucceeded(this);
            }
            return(this.consumed);
        }
        private bool cancelHold(IAssetCallback assetCallbacks, GloebitAPIWrapper.ITransactionAlert transactionAlerts, out string returnMsg)
        {
            if (this.consumed)
            {
                // Should never get a delayed cancel after a consume.  return false.
                returnMsg = "Cancel: already consumed";
                return(false);
            }
            if (!this.enacted)
            {
                // Hasn't enacted.  No work to undo.  return true.
                returnMsg = "Cancel: not yet enacted";
                // don't return here.  Still want to process cancel which will need to assess if enacted.
                //return true;
            }
            if (this.canceled)
            {
                // already canceled. return true.
                returnMsg = "Cancel: already canceled";
                return(true);
            }
            // First reception of cancel for asset.
            // Send alert that CANCEL_GLOEBIT has completed
            transactionAlerts.AlertTransactionStageCompleted(this, GloebitAPI.TransactionStage.CANCEL_GLOEBIT, String.Empty);
            // Do specific cancel functionality for the Asset / local transaction part
            this.canceled = assetCallbacks.processAssetCancelHold(this, out returnMsg); // Do I need to grab the money module for this?
            if (this.canceled)
            {
                this.finishedTime = DateTime.UtcNow;
                GloebitTransactionData.Instance.Store(this);

                // send alert that CANCEL_ASSET has completed
                // TODO: should we pass the returnMsg instead of String.Empty, or is this always empty on success? -- investigate
                transactionAlerts.AlertTransactionStageCompleted(this, GloebitAPI.TransactionStage.CANCEL_ASSET, String.Empty);
            }
            return(this.canceled);
        }
        private bool enactHold(IAssetCallback assetCallbacks, GloebitAPIWrapper.ITransactionAlert transactionAlerts, out string returnMsg)
        {
            if (this.canceled)
            {
                // getting a delayed enact sent before cancel.  return false.
                returnMsg = "Enact: already canceled";
                return(false);
            }
            if (this.consumed)
            {
                // getting a delayed enact sent before consume.  return true.
                returnMsg = "Enact: already consumed";
                return(true);
            }
            if (this.enacted)
            {
                // already enacted. return true.
                returnMsg = "Enact: already enacted";
                return(true);
            }
            // First reception of enact for asset.
            // Send alert that ENACT_GLOEBIT has completed
            transactionAlerts.AlertTransactionStageCompleted(this, GloebitAPI.TransactionStage.ENACT_GLOEBIT, String.Empty);
            // Do specific enact functionality for the Asset / local transaction part
            this.enacted = assetCallbacks.processAssetEnactHold(this, out returnMsg);

            // TODO: remove this after testing.
            m_log.InfoFormat("[GLOEBITMONEYMODULE] GloebitTransaction.enactHold: {0}", this.enacted);
            if (this.enacted)
            {
                m_log.InfoFormat("TransactionID: {0}", this.TransactionID);
                m_log.DebugFormat("PayerID: {0}", this.PayerID);
                m_log.DebugFormat("PayeeID: {0}", this.PayeeID);
                m_log.DebugFormat("PartID: {0}", this.PartID);
                m_log.DebugFormat("PartName: {0}", this.PartName);
                m_log.DebugFormat("CategoryID: {0}", this.CategoryID);
                m_log.DebugFormat("SaleType: {0}", this.SaleType);
                m_log.DebugFormat("Amount: {0}", this.Amount);
                m_log.DebugFormat("PayerEndingBalance: {0}", this.PayerEndingBalance);
                m_log.DebugFormat("enacted: {0}", this.enacted);
                m_log.DebugFormat("consumed: {0}", this.consumed);
                m_log.DebugFormat("canceled: {0}", this.canceled);
                m_log.DebugFormat("cTime: {0}", this.cTime);
                m_log.DebugFormat("enactedTime: {0}", this.enactedTime);
                m_log.DebugFormat("finishedTime: {0}", this.finishedTime);

                // TODO: Should we store and update the time even if it fails to track time enact attempted/failed?
                this.enactedTime = DateTime.UtcNow;
                GloebitTransactionData.Instance.Store(this);

                // send alert that ENACT_ASSET has completed
                // TODO: should we pass the returnMsg instead of String.Empty, or is this always empty on success? -- investigate
                transactionAlerts.AlertTransactionStageCompleted(this, GloebitAPI.TransactionStage.ENACT_ASSET, String.Empty);
            }
            else if (returnMsg != "pending")
            {
                // If pending, this is not a permanent failure and enact will be retried
                // not sure that platform should ever need to fail with pending, but being extra cautious
                // Local Asset Enact failed - Fire alert
                transactionAlerts.AlertTransactionFailed(this, GloebitAPI.TransactionStage.ENACT_ASSET, GloebitAPI.TransactionFailure.ENACTING_ASSET_FAILED, returnMsg, null);
            }
            return(this.enacted);
        }