internal async Task DoSendAsync(ActiveMQDestination destination, ActiveMQMessage message,
                                        MessageProducer producer, MemoryUsage producerWindow, TimeSpan sendTimeout)
        {
            ActiveMQMessage msg = message;

            if (destination.IsTemporary && !connection.IsTempDestinationActive(destination as ActiveMQTempDestination))
            {
                throw new InvalidDestinationException("Cannot publish to a deleted Destination: " + destination);
            }

            if (IsTransacted)
            {
                DoStartTransaction();
                msg.TransactionId = TransactionContext.TransactionId;
            }

            msg.RedeliveryCounter = 0;
            msg.BrokerPath        = null;

            if (this.connection.CopyMessageOnSend)
            {
                msg = (ActiveMQMessage)msg.Clone();
            }

            msg.OnSend();
            msg.ProducerId = msg.MessageId.ProducerId;

            if (sendTimeout.TotalMilliseconds <= 0 && !msg.ResponseRequired && !connection.AlwaysSyncSend &&
                (!msg.Persistent || connection.AsyncSend || msg.TransactionId != null))
            {
                this.connection.Oneway(msg);

                if (producerWindow != null)
                {
                    // Since we defer lots of the marshaling till we hit the wire, this
                    // might not provide and accurate size. We may change over to doing
                    // more aggressive marshaling, to get more accurate sizes.. this is more
                    // important once users start using producer window flow control.
                    producerWindow.IncreaseUsage(msg.Size());
                }
            }
            else
            {
                if (sendTimeout.TotalMilliseconds > 0)
                {
                    await this.connection.SyncRequestAsync(msg, sendTimeout).Await();
                }
                else
                {
                    await this.connection.SyncRequestAsync(msg).Await();
                }
            }
        }