/// <summary>
        /// Bootstrap one or more Amazon AWS Virtual Private Cloud (VPC) instances and adds
        /// them to ConDep's servers collection. This method assume mandatory settings are
        /// found in ConDep's environment file. If you prefer to specify settings directly, use
        /// the other overload and specify settings in code.
        /// </summary>
        /// <param name="ec2"></param>
        /// <param name="tags">Tags to use as identifiers to ensure the idempotency of the bootstrap operation.
        /// Make sure that the tag(s) used uniquely identifies instances you want to manage by your ConDep operation.</param>
        /// <returns></returns>
        public static Result CreateInstances(this IOfferAwsEc2Operations ec2, Action <IOfferAwsTagOptions> tags)
        {
            var ec2Builder = ec2 as AwsEc2OperationsBuilder;

            var instanceOptions       = new AwsBootstrapOptionsBuilder(tags);
            var awsBootstrapOperation = new AwsBootstrapOperation(instanceOptions.Values);

            OperationExecutor.Execute((LocalBuilder)ec2, awsBootstrapOperation);
            return(ec2Builder.Result);
        }
        /// <summary>
        /// Bootstrap one or more Amazon AWS Virtual Private Cloud (VPC) instances and adds
        /// them to ConDep's servers collection. This method assume mandatory settings are
        /// found in ConDep's environment file. If you prefer to specify settings directly, use
        /// the other overload and specify settings in code.
        /// </summary>
        /// <param name="ec2"></param>
        /// <param name="bootstrapId">Unique, case-sensitive identifier you provide to ensure the idempotency of the bootstrap operation.
        /// In AWS this is refered to as the Client Token.</param>
        /// <returns></returns>
        public static Result CreateInstances(this IOfferAwsEc2Operations ec2, string bootstrapId)
        {
            var ec2Builder = ec2 as AwsEc2OperationsBuilder;

            var options = new AwsBootstrapOptionsValues(bootstrapId);
            var awsBootstrapOperation = new AwsBootstrapOperation(options);

            OperationExecutor.Execute((LocalBuilder)ec2, awsBootstrapOperation);
            return(ec2Builder.Result);
        }
        public static Result CreateImage(this IOfferAwsEc2Operations ec2, string instanceId, string imageName, Action <IOfferAwsImageCreateOptions> options = null)
        {
            var ec2Builder = ec2 as AwsEc2OperationsBuilder;

            var imageOptions = new AwsImageCreateOptionsBuilder(instanceId, imageName);

            options?.Invoke(imageOptions);

            var awsCreateImageOperation = new AwsCreateImageOperation(imageOptions.Values);

            OperationExecutor.Execute((LocalBuilder)ec2, awsCreateImageOperation);
            return(ec2Builder.Result);
        }
        /// <summary>
        /// Deregister images based on a filter
        /// </summary>
        /// <param name="ec2"></param>
        /// <param name="filterOptions">Filter to describe images to deregister</param>
        /// <returns></returns>
        public static Result DeregisterImages(this IOfferAwsEc2Operations ec2, Action <IOfferAwsImageDescribeOptions> filterOptions, Action <IOfferAwsImageDeregisterOptions> deregisterOptions = null)
        {
            var ec2Builder           = ec2 as AwsEc2OperationsBuilder;
            var imageDescribeOptions = new AwsImageDescribeOptionsBuilder();

            filterOptions.Invoke(imageDescribeOptions);

            var imageDeregisterOptions = new AwsImageDeregisterOptionsBuilder();

            deregisterOptions?.Invoke(imageDeregisterOptions);

            var awsDeregisterImagesOperation = new AwsDeregisterImagesOperation(imageDescribeOptions.Values, imageDeregisterOptions.Values);

            OperationExecutor.Execute((LocalBuilder)ec2, awsDeregisterImagesOperation);
            return(ec2Builder.Result);
        }
        /// <summary>
        /// Search for AWS intances based on tags
        /// </summary>
        /// <param name="ec2"></param>
        /// <param name="tags">The tags to match</param>
        /// <returns></returns>
        public static Result DiscoverInstances(this IOfferAwsEc2Operations ec2, Action <IOfferAwsTagOptions> tags, Action <IOfferAwsEc2DiscoverOptions> options = null)
        {
            var ec2Builder = ec2 as AwsEc2OperationsBuilder;

            var tagValues  = new List <KeyValuePair <string, string> >();
            var tagOptions = new AwsBootstrapTagOptionsBuilder(tagValues);

            tags(tagOptions);

            var awsOptions = new AwsEc2DiscoverOptionsBuilder();

            if (options != null)
            {
                options(awsOptions);
            }

            var awsEc2DiscoverOperation = new AwsEc2DiscoverOperation(tagValues, awsOptions.Values);

            OperationExecutor.Execute((LocalBuilder)ec2, awsEc2DiscoverOperation);
            return(ec2Builder.Result);
        }