public virtual ITransactionEnvelope GenerateNeuraliumMultiTransferTransaction(Guid accountUuid, List <RecipientSet> recipients, Amount tip, CorrelationContext correlationContext)
        {
            try {
                INeuraliumMultiTransferTransaction multiTransferTransaction = new NeuraliumMultiTransferTransaction();

                ITransactionEnvelope envelope = this.GenerateTransaction(multiTransferTransaction, GlobalsService.TRANSACTION_KEY_NAME, EnvelopeSignatureTypes.Instance.Published, () => {
                    multiTransferTransaction.Recipients.AddRange(recipients);
                    multiTransferTransaction.Total = recipients.Sum(e => e.Amount);
                    multiTransferTransaction.Tip   = tip;

                    // let's ensure we have the balance
                    Amount balance = this.CentralCoordinator.ChainComponentProvider.WalletProvider.GetAccountBalance(accountUuid, false).Total;

                    // make sure that the amount spent and tip are less than what we have in total

                    if ((balance - (multiTransferTransaction.Total + tip)) < 0)
                    {
                        //TODO: what to do here?
                        throw new InvalidOperationException("We don't have enough to transfer");
                    }
                });

                return(envelope);
            } catch (Exception ex) {
                throw new ApplicationException("failed to generate neuralium key change transaction", ex);
            }
        }
        private ITransaction CreateTransation(ComponentVersion <TransactionType> version)
        {
            ITransaction transaction = null;

            if (transaction == null)
            {
                if (version.Type == TransactionTypes.Instance.GENESIS)
                {
                    if (version == (1, 0))
                    {
                        transaction = new NeuraliumGenesisModeratorAccountPresentationTransaction();
                    }
                }
                else if (version.Type == TransactionTypes.Instance.MODERATION_PRESENTATION)
                {
                    if (version == (1, 0))
                    {
                        transaction = new NeuraliumGenesisAccountPresentationTransaction();
                    }
                }
                else if (version.Type == TransactionTypes.Instance.MODERATION_ELECTION_POOL_PRESENTATION)
                {
                    if (version == (1, 0))
                    {
                        transaction = new NeuraliumGenesisElectionPoolPresentationTransaction();
                    }
                }
                else if (version.Type == TransactionTypes.Instance.SIMPLE_PRESENTATION)
                {
                    if (version == (1, 0))
                    {
                        transaction = new NeuraliumStandardPresentationTransaction();
                    }
                }
                else if (version.Type == TransactionTypes.Instance.JOINT_PRESENTATION)
                {
                    if (version == (1, 0))
                    {
                        transaction = new NeuraliumJointPresentationTransaction();
                    }
                }
                else if (version.Type == TransactionTypes.Instance.KEY_CHANGE)
                {
                    if (version == (1, 0))
                    {
                        transaction = new NeuraliumStandardAccountKeyChangeTransaction();
                    }
                }
                else if (version.Type == TransactionTypes.Instance.SET_ACCOUNT_RECOVERY)
                {
                    if (version == (1, 0))
                    {
                        transaction = new NeuraliumSetAccountRecoveryTransaction();
                    }
                }
                else if (version.Type == TransactionTypes.Instance.MODERATION_OPERATING_RULES)
                {
                    if (version == (1, 0))
                    {
                        transaction = new NeuraliumChainOperatingRulesTransaction();
                    }
                }
                else if (version.Type == TransactionTypes.Instance.ACCREDITATION_CERTIFICATE)
                {
                    if (version == (1, 0))
                    {
                        transaction = new NeuraliumChainAccreditationCertificateTransaction();
                    }
                }
                else if (version.Type == TransactionTypes.Instance.DEBUG)
                {
                    if (version == (1, 0))
                    {
                        transaction = new NeuraliumDebugTransaction();
                    }
                }
                else if (version.Type == TransactionTypes.Instance.MODERATION_KEY_CHANGE)
                {
                    if (version == (1, 0))
                    {
                        transaction = new NeuraliumModeratorKeyChangeTransaction();
                    }
                }
                else if (version.Type == TransactionTypes.Instance.MODERATION_RECLAIM_ACCOUNTS)
                {
                    if (version == (1, 0))
                    {
                        transaction = new NeuraliumReclaimAccountsTransaction();
                    }
                }
                else if (version.Type == TransactionTypes.Instance.MODERATION_ACCOUNT_RESET_WARNING)
                {
                    if (version == (1, 0))
                    {
                        transaction = new NeuraliumAccountResetWarningTransaction();
                    }
                }
                else if (version.Type == TransactionTypes.Instance.MODERATION_ACCOUNT_RESET)
                {
                    if (version == (1, 0))
                    {
                        transaction = new NeuraliumAccountResetTransaction();
                    }
                }

                // neuralium only transactions

                else if (version.Type == NeuraliumTransactionTypes.Instance.NEURALIUM_TRANSFER)
                {
                    if (version == (1, 0))
                    {
                        transaction = new NeuraliumTransferTransaction();
                    }
                }
                else if (version.Type == NeuraliumTransactionTypes.Instance.NEURALIUM_MULTI_TRANSFER)
                {
                    if (version == (1, 0))
                    {
                        transaction = new NeuraliumMultiTransferTransaction();
                    }
                }
                else if (version.Type == NeuraliumTransactionTypes.Instance.NEURALIUM_MODERATOR_DESTROY_TOKENS)
                {
                    if (version == (1, 0))
                    {
                        transaction = new DestroyNeuraliumsTransaction();
                    }
                }
                else if (version.Type == NeuraliumTransactionTypes.Instance.NEURALIUM_FREEZE_SUSPICIOUSACCOUNTS)
                {
                    if (version == (1, 0))
                    {
                        transaction = new NeuraliuFreezeSuspiciousFundsTransaction();
                    }
                }
                else if (version.Type == NeuraliumTransactionTypes.Instance.NEURALIUM_UNWIND_STOLEN_SUSPICIOUSACCOUNTS)
                {
                    if (version == (1, 0))
                    {
                        transaction = new NeuraliumUnwindStolenFundsTreeTransaction();
                    }
                }
                else if (version.Type == NeuraliumTransactionTypes.Instance.NEURALIUM_UNFREEZE_SUSPICIOUSACCOUNTS)
                {
                    if (version == (1, 0))
                    {
                        transaction = new NeuraliuUnfreezeClearedFundsTransaction();
                    }
                }
                else if (version.Type == NeuraliumTransactionTypes.Instance.NEURALIUM_SAFU_TRANSFER)
                {
                    if (version == (1, 0))
                    {
                        transaction = new NeuraliumSAFUTransferTransaction();
                    }
                }
                else if (version.Type == NeuraliumTransactionTypes.Instance.NEURALIUM_SAFU_CONTRIBUTIONS)
                {
                    if (version == (1, 0))
                    {
                        transaction = new NeuraliumSAFUContributionTransaction();
                    }
                }
#if TESTNET || DEVNET
                else if (version.Type == NeuraliumTransactionTypes.Instance.NEURALIUM_REFILL_NEURLIUMS)
                {
                    if (version == (1, 0))
                    {
                        transaction = new NeuraliumRefillNeuraliumsTransaction();
                    }
                }
#endif

                else
                {
                    throw new ApplicationException("Invalid transaction type");
                }
            }

            return(transaction);
        }