/// <summary>
        /// Subscribes an existing Amazon SQS queue to existing Amazon SNS topics.
        /// <para>
        /// The policy applied to the SQS queue is similar to this:
        /// <code>
        /// {
        ///     "Version" : "2008-10-17",
        ///     "Statement" : [{
        ///         "Sid" : "topic-subscription-arn:aws:sns:us-west-2:599109622955:myTopic",
        ///         "Effect" : "Allow",
        ///         "Principal" : "*",
        ///         "Action" : ["sqs:SendMessage"],
        ///         "Resource":["arn:aws:sqs:us-west-2:599109622955:myQueue"],
        ///         "Condition" : {
        ///             "ArnLike":{
        ///                 "aws:SourceArn":["arn:aws:sns:us-west-2:599109622955:myTopic"]
        ///             }
        ///         }
        ///     }]
        /// }
        /// </code>
        /// </para>
        /// <para>
        /// There might be a small time period immediately after
        /// subscribing the SQS queue to the SNS topic and updating the SQS queue's
        /// policy, where messages are not able to be delivered to the queue. After a
        /// moment, the new queue policy will propagate and the queue will be able to
        /// receive messages. This delay only occurs immediately after initially
        /// subscribing the queue.
        /// </para>
        /// </summary>
        /// <param name="topicArns">The topics to subscribe to</param>
        /// <param name="sqsClient">The SQS client used to get attributes and set the policy on the SQS queue.</param>
        /// <param name="sqsQueueUrl">The queue to add a subscription to.</param>
        /// <returns>The mapping of topic ARNs to subscription ARNs as returned by Amazon SNS when the queue is
        /// successfully subscribed to each topic.</returns>
        public IDictionary <string, string> SubscribeQueueToTopics(IList <string> topicArns, ICoreAmazonSQS sqsClient, string sqsQueueUrl)
        {
            // Get the queue's existing policy and ARN
            var queueAttributes = sqsClient.GetAttributes(sqsQueueUrl);

            string sqsQueueArn = queueAttributes["QueueArn"];

            Policy policy;
            string policyStr = null;

            if (queueAttributes.ContainsKey("Policy"))
            {
                policyStr = queueAttributes["Policy"];
            }
            if (string.IsNullOrEmpty(policyStr))
            {
                policy = new Policy();
            }
            else
            {
                policy = Policy.FromJson(policyStr);
            }

            var subscriptionArns = new Dictionary <string, string>();

            foreach (var topicArn in topicArns)
            {
                if (!HasSQSPermission(policy, topicArn, sqsQueueArn))
                {
                    AddSQSPermission(policy, topicArn, sqsQueueArn);
                }

                var arn = this.Subscribe(new SubscribeRequest
                {
                    TopicArn = topicArn,
                    Protocol = "sqs",
                    Endpoint = sqsQueueArn
                }).SubscriptionArn;

                subscriptionArns.Add(topicArn, arn);
            }

            var setAttributes = new Dictionary <string, string> {
                { "Policy", policy.ToJson() }
            };

            sqsClient.SetAttributes(sqsQueueUrl, setAttributes);

            return(subscriptionArns);
        }
        /// <summary>
        /// Subscribes an existing Amazon SQS queue to existing Amazon SNS topics.
        /// <para>
        /// The policy applied to the SQS queue is similar to this:
        /// <code>
        /// {
        /// 	"Version" : "2008-10-17",
        /// 	"Statement" : [{
        /// 	    "Sid" : "topic-subscription-arn:aws:sns:us-west-2:599109622955:myTopic",
        /// 		"Effect" : "Allow",
        /// 		"Principal" : "*",
        /// 		"Action" : ["sqs:SendMessage"],
        /// 		"Resource":["arn:aws:sqs:us-west-2:599109622955:myQueue"],
        /// 		"Condition" : {
        /// 			"ArnLike":{
        /// 				"aws:SourceArn":["arn:aws:sns:us-west-2:599109622955:myTopic"]
        /// 			}
        /// 		}
        ///     }]
        /// }
        /// </code>
        /// </para>
        /// <para>
        /// There might be a small time period immediately after
        /// subscribing the SQS queue to the SNS topic and updating the SQS queue's
        /// policy, where messages are not able to be delivered to the queue. After a
        /// moment, the new queue policy will propagate and the queue will be able to
        /// receive messages. This delay only occurs immediately after initially
        /// subscribing the queue.
        /// </para>
        /// </summary>
        /// <param name="topicArns">The topics to subscribe to</param>
        /// <param name="sqsClient">The SQS client used to get attributes and set the policy on the SQS queue.</param>
        /// <param name="sqsQueueUrl">The queue to add a subscription to.</param>
        /// <returns>The mapping of topic ARNs to subscription ARNs as returned by Amazon SNS when the queue is 
        /// successfully subscribed to each topic.</returns>
        public IDictionary<string, string> SubscribeQueueToTopics(IList<string> topicArns, ICoreAmazonSQS sqsClient, string sqsQueueUrl)
        {
            // Get the queue's existing policy and ARN
            var queueAttributes = sqsClient.GetAttributes(sqsQueueUrl);

            string sqsQueueArn = queueAttributes["QueueArn"];

            Policy policy;
            string policyStr = null;
            if(queueAttributes.ContainsKey("Policy"))
                policyStr = queueAttributes["Policy"];
            if (string.IsNullOrEmpty(policyStr))
                policy = new Policy();
            else
                policy = Policy.FromJson(policyStr);

            var subscriptionArns = new Dictionary<string,string>();

            foreach (var topicArn in topicArns)
            {
 				if (!HasSQSPermission(policy, topicArn, sqsQueueArn))
                    AddSQSPermission(policy, topicArn, sqsQueueArn);

                var arn = this.Subscribe(new SubscribeRequest
                {
                    TopicArn = topicArn,
                    Protocol = "sqs",
                    Endpoint = sqsQueueArn
                }).SubscriptionArn;

                subscriptionArns.Add(topicArn, arn);
            }

            var setAttributes = new Dictionary<string, string> { { "Policy", policy.ToJson() } };
            sqsClient.SetAttributes(sqsQueueUrl, setAttributes);

            return subscriptionArns;
        }