/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.jclouds.aws.ec2.compute;

import static com.google.common.base.Objects.equal;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.base.Strings.emptyToNull;

import java.util.Map;
import java.util.Set;

import org.jclouds.aws.ec2.options.RequestSpotInstancesOptions;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.domain.LoginCredentials;
import org.jclouds.ec2.compute.options.EC2TemplateOptions;
import org.jclouds.ec2.domain.BlockDeviceMapping;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.rest.annotations.SinceApiVersion;
import org.jclouds.scriptbuilder.domain.Statement;

import com.google.common.base.Objects;
import com.google.common.base.Objects.ToStringHelper;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;

/**
 * Contains options supported in the {@code ComputeService#runNode} operation on
 * the "ec2" provider. <h2>
 * Usage</h2> The recommended way to instantiate a AWSEC2TemplateOptions object
 * is to statically import AWSEC2TemplateOptions.* and invoke a static creation
 * method followed by an instance mutator (if needed):
 * <p/>
 * <code>
 * import static org.jclouds.aws.ec2.compute.options.AWSEC2TemplateOptions.Builder.*;
 * <p/>
 * ComputeService client = // get connection
 * templateBuilder.options(inboundPorts(22, 80, 8080, 443));
 * Set<? extends NodeMetadata> set = client.createNodesInGroup(tag, 2, templateBuilder.build());
 * <code>
 */
public class AWSEC2TemplateOptions extends EC2TemplateOptions implements Cloneable {
   @Override
   public AWSEC2TemplateOptions clone() {
      AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
      copyTo(options);
      return options;
   }

   @Override
   public void copyTo(TemplateOptions to) {
      super.copyTo(to);
      if (to instanceof AWSEC2TemplateOptions) {
         AWSEC2TemplateOptions eTo = AWSEC2TemplateOptions.class.cast(to);
         if (getSubnetId() != null)
            eTo.subnetId(getSubnetId());
         if (getIAMInstanceProfileArn() != null)
            eTo.iamInstanceProfileArn(getIAMInstanceProfileArn());
         if (getIAMInstanceProfileName() != null)
            eTo.iamInstanceProfileName(getIAMInstanceProfileName());
         if (isMonitoringEnabled())
            eTo.enableMonitoring();
         if (!shouldAutomaticallyCreatePlacementGroup())
            eTo.noPlacementGroup();
         if (getPlacementGroup() != null)
            eTo.placementGroup(getPlacementGroup());
         if (getGroupIds().size() > 0)
            eTo.securityGroupIds(getGroupIds());
         if (getSpotPrice() != null)
            eTo.spotPrice(getSpotPrice());
         if (getSpotOptions() != null)
            eTo.spotOptions(getSpotOptions());
         if (getPrivateIpAddress() != null)
            eTo.privateIpAddress(getPrivateIpAddress());
      }
   }

   private boolean monitoringEnabled;
   private String placementGroup = null;
   private boolean noPlacementGroup;
   private String subnetId;
   private Float spotPrice;
   private RequestSpotInstancesOptions spotOptions = RequestSpotInstancesOptions.NONE;
   private Set<String> groupIds = ImmutableSet.of();
   private String iamInstanceProfileArn;
   private String iamInstanceProfileName;
   private String privateIpAddress;

   @Override
   public boolean equals(Object o) {
      if (this == o)
         return true;
      if (o == null || getClass() != o.getClass())
         return false;
      AWSEC2TemplateOptions that = AWSEC2TemplateOptions.class.cast(o);
      return super.equals(that) && equal(this.monitoringEnabled, that.monitoringEnabled)
               && equal(this.placementGroup, that.placementGroup)
               && equal(this.noPlacementGroup, that.noPlacementGroup) && equal(this.subnetId, that.subnetId)
               && equal(this.spotPrice, that.spotPrice) && equal(this.spotOptions, that.spotOptions)
               && equal(this.groupIds, that.groupIds) && equal(this.iamInstanceProfileArn, that.iamInstanceProfileArn)
               && equal(this.iamInstanceProfileName, that.iamInstanceProfileName)
               && equal(this.privateIpAddress, that.privateIpAddress);
   }

   @Override
   public int hashCode() {
      return Objects.hashCode(super.hashCode(), monitoringEnabled, placementGroup, noPlacementGroup, subnetId,
               spotPrice, spotOptions, groupIds, iamInstanceProfileArn, iamInstanceProfileName, privateIpAddress);
   }

   @Override
   public ToStringHelper string() {
      ToStringHelper toString = super.string();
      if (monitoringEnabled)
         toString.add("monitoringEnabled", monitoringEnabled);
      toString.add("placementGroup", placementGroup);
      if (noPlacementGroup)
         toString.add("noPlacementGroup", noPlacementGroup);
      toString.add("subnetId", subnetId);
      toString.add("spotPrice", spotPrice);
      if (spotOptions != RequestSpotInstancesOptions.NONE)
         toString.add("spotOptions", spotOptions);
      if (groupIds.size() != 0)
         toString.add("groupIds", groupIds);
      toString.add("iamInstanceProfileArn", iamInstanceProfileArn);
      toString.add("iamInstanceProfileName", iamInstanceProfileName);
      toString.add("privateIpAddress", privateIpAddress);
      return toString;
   }

   public static final AWSEC2TemplateOptions NONE = new AWSEC2TemplateOptions();

   /**
    * Enable Cloudwatch monitoring
    * 
    * @see CloudWatchClient
    */
   public AWSEC2TemplateOptions enableMonitoring() {
      this.monitoringEnabled = true;
      return this;
   }

   /**
    * Specifies the keypair used to run instances with
    */
   public AWSEC2TemplateOptions placementGroup(String placementGroup) {
      checkNotNull(emptyToNull(placementGroup), "use noPlacementGroup option instead of passing null");
      checkState(!noPlacementGroup, "you cannot specify both options placementGroup and noPlacementGroup");
      this.placementGroup = placementGroup;
      return this;
   }

   /**
    * Do not use a keypair on instances
    */
   public AWSEC2TemplateOptions noPlacementGroup() {
      checkState(placementGroup == null, "you cannot specify both options placementGroup and noPlacementGroup");
      this.noPlacementGroup = true;
      return this;
   }

   /**
    * Specifies the subnetId used to run instances in
    */
   public AWSEC2TemplateOptions subnetId(String subnetId) {
      this.subnetId = checkNotNull(emptyToNull(subnetId), "subnetId must be defined");
      return this;
   }

   /**
    * @see org.jclouds.aws.ec2.options.AWSRunInstancesOptions#withIAMInstanceProfileArn(String)
    */
   @SinceApiVersion("2012-06-01")
   public AWSEC2TemplateOptions iamInstanceProfileArn(String arn) {
      this.iamInstanceProfileArn = checkNotNull(emptyToNull(arn), "arn must be defined");
      return this;
   }

   /**
    * @see org.jclouds.aws.ec2.options.AWSRunInstancesOptions#withIAMInstanceProfileName(String)
    */
   @SinceApiVersion("2012-06-01")
   public AWSEC2TemplateOptions iamInstanceProfileName(String name) {
      this.iamInstanceProfileName = checkNotNull(emptyToNull(name), "name must be defined");
      return this;
   }

   public AWSEC2TemplateOptions privateIpAddress(String address) {
      this.privateIpAddress = checkNotNull(emptyToNull(address), "address must be defined");
      return this;
   }

   /**
    * Specifies the maximum spot price to use
    */
   public AWSEC2TemplateOptions spotPrice(Float spotPrice) {
      this.spotPrice = spotPrice;
      return this;
   }

   /**
    * Options for starting spot instances
    */
   public AWSEC2TemplateOptions spotOptions(RequestSpotInstancesOptions spotOptions) {
      this.spotOptions = spotOptions != null ? spotOptions : RequestSpotInstancesOptions.NONE;
      return this;
   }

   /**
    * 
    * @see AWSEC2TemplateOptions#securityGroupIds(Iterable<String>)
    */
   public AWSEC2TemplateOptions securityGroupIds(String... groupIds) {
      return securityGroupIds(ImmutableSet.copyOf(groupIds));
   }

   /**
    * Specifies the security group ids to be used for nodes with this template
    */
   public AWSEC2TemplateOptions securityGroupIds(Iterable<String> groupIds) {
      checkArgument(Iterables.size(groupIds) > 0, "you must specify at least one security group");
      for (String groupId : groupIds)
         checkNotNull(emptyToNull(groupId), "all security groups must be non-empty");
      this.groupIds = ImmutableSet.copyOf(groupIds);
      return this;
   }

   public Set<String> getGroupIds() {
      return groupIds;
   }

   public static class Builder {

      public static AWSEC2TemplateOptions overrideLoginUser(String user) {
         AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
         return options.overrideLoginUser(user);
      }

      public static AWSEC2TemplateOptions overrideLoginPassword(String password) {
         AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
         return options.overrideLoginPassword(password);
      }

      public static AWSEC2TemplateOptions overrideLoginPrivateKey(String privateKey) {
         AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
         return options.overrideLoginPrivateKey(privateKey);
      }

      public static AWSEC2TemplateOptions overrideAuthenticateSudo(boolean authenticateSudo) {
         AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
         return options.overrideAuthenticateSudo(authenticateSudo);
      }

      public static AWSEC2TemplateOptions overrideLoginCredentials(LoginCredentials credentials) {
         AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
         return options.overrideLoginCredentials(credentials);
      }

      /**
       * @see AWSEC2TemplateOptions#securityGroupIds(Iterable<String>)
       */
      public static AWSEC2TemplateOptions securityGroupIds(String... groupNames) {
         AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
         return AWSEC2TemplateOptions.class.cast(options.securityGroupIds(groupNames));
      }

      /**
       * @see AWSEC2TemplateOptions#securityGroupIds(Iterable<String>)
       */
      public static AWSEC2TemplateOptions securityGroupIds(Iterable<String> groupNames) {
         AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
         return AWSEC2TemplateOptions.class.cast(options.securityGroupIds(groupNames));
      }

      /**
       * @see EC2TemplateOptions#blockDeviceMappings
       */
      public static AWSEC2TemplateOptions blockDeviceMappings(Set<? extends BlockDeviceMapping> blockDeviceMappings) {
         AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
         return options.blockDeviceMappings(blockDeviceMappings);
      }

      /**
       * @see EC2TemplateOptions#mapEBSSnapshotToDeviceName
       */
      public static AWSEC2TemplateOptions mapEBSSnapshotToDeviceName(String deviceName, String snapshotId,
            @Nullable Integer sizeInGib, boolean deleteOnTermination) {
         AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
         return options.mapEBSSnapshotToDeviceName(deviceName, snapshotId, sizeInGib, deleteOnTermination);
      }

      /**
       * @see EC2TemplateOptions#mapNewVolumeToDeviceName
       */
      public static AWSEC2TemplateOptions mapNewVolumeToDeviceName(String deviceName, int sizeInGib,
            boolean deleteOnTermination) {
         AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
         return options.mapNewVolumeToDeviceName(deviceName, sizeInGib, deleteOnTermination);
      }

      /**
       * @see EC2TemplateOptions#mapEphemeralDeviceToDeviceName
       */
      public static AWSEC2TemplateOptions mapEphemeralDeviceToDeviceName(String deviceName, String virtualName) {
         AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
         return options.mapEphemeralDeviceToDeviceName(deviceName, virtualName);
      }

      /**
       * @see EC2TemplateOptions#unmapDeviceNamed
       */
      public static AWSEC2TemplateOptions unmapDeviceNamed(String deviceName) {
         AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
         return options.unmapDeviceNamed(deviceName);
      }

      /**
       * @see AWSEC2TemplateOptions#securityGroups(Iterable<String>)
       */
      public static AWSEC2TemplateOptions securityGroups(String... groupIds) {
         AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
         return options.securityGroups(groupIds);
      }

      /**
       * @see AWSEC2TemplateOptions#securityGroups(Iterable<String>)
       */
      public static AWSEC2TemplateOptions securityGroups(Iterable<String> groupIds) {
         AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
         return options.securityGroups(groupIds);
      }

      /**
       * @see AWSEC2TemplateOptions#keyPair
       */
      public static AWSEC2TemplateOptions keyPair(String keyPair) {
         AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
         return options.keyPair(keyPair);
      }

      /**
       * @see AWSEC2TemplateOptions#userData
       */
      public static AWSEC2TemplateOptions userData(byte[] unencodedData) {
         AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
         return options.userData(unencodedData);
      }

      /**
       * @see AWSEC2TemplateOptions#noKeyPair
       */
      public static AWSEC2TemplateOptions noKeyPair() {
         AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
         return options.noKeyPair();
      }

      /**
       * @see AWSEC2TemplateOptions#placementGroup
       */
      public static AWSEC2TemplateOptions placementGroup(String placementGroup) {
         AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
         return options.placementGroup(placementGroup);
      }

      /**
       * @see AWSEC2TemplateOptions#noPlacementGroup
       */
      public static AWSEC2TemplateOptions noPlacementGroup() {
         AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
         return options.noPlacementGroup();
      }

      /**
       * @see AWSEC2TemplateOptions#enableMonitoring
       */
      public static AWSEC2TemplateOptions enableMonitoring() {
         AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
         return options.enableMonitoring();
      }

      // methods that only facilitate returning the correct object type
      /**
       * @see TemplateOptions#inboundPorts
       */
      public static AWSEC2TemplateOptions inboundPorts(int... ports) {
         AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
         return options.inboundPorts(ports);
      }

      /**
       * @see TemplateOptions#port
       */
      public static AWSEC2TemplateOptions blockOnPort(int port, int seconds) {
         AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
         return options.blockOnPort(port, seconds);
      }

      /**
       * @see TemplateOptions#installPrivateKey
       */
      public static AWSEC2TemplateOptions installPrivateKey(String rsaKey) {
         AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
         return options.installPrivateKey(rsaKey);
      }

      /**
       * @see TemplateOptions#authorizePublicKey
       */
      public static AWSEC2TemplateOptions authorizePublicKey(String rsaKey) {
         AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
         return options.authorizePublicKey(rsaKey);
      }

      /**
       * @see AWSEC2TemplateOptions#subnetId
       */
      public static AWSEC2TemplateOptions subnetId(String subnetId) {
         AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
         return options.subnetId(subnetId);
      }

      /**
       * @see AWSEC2TemplateOptions#iamInstanceProfileArn
       */
      @SinceApiVersion("2012-06-01")
      public static AWSEC2TemplateOptions iamInstanceProfileArn(String arn) {
         AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
         return options.iamInstanceProfileArn(arn);
      }

      /**
       * @see AWSEC2TemplateOptions#iamInstanceProfileName
       */
      @SinceApiVersion("2012-06-01")
      public static AWSEC2TemplateOptions iamInstanceProfileName(String name) {
         AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
         return options.iamInstanceProfileName(name);
      }

      public static AWSEC2TemplateOptions privateIpAddress(String address) {
         AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
         return options.privateIpAddress(address);
      }

      /**
       * @see AWSEC2TemplateOptions#spotPrice
       */
      public static AWSEC2TemplateOptions spotPrice(Float spotPrice) {
         AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
         return options.spotPrice(spotPrice);
      }

      /**
       * @see AWSEC2TemplateOptions#spotOptions
       */
      public static AWSEC2TemplateOptions spotOptions(RequestSpotInstancesOptions spotOptions) {
         AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
         return options.spotOptions(spotOptions);
      }

      /**
       * @see TemplateOptions#userMetadata(Map)
       */
      public static AWSEC2TemplateOptions userMetadata(Map<String, String> userMetadata) {
         AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
         return AWSEC2TemplateOptions.class.cast(options.userMetadata(userMetadata));
      }

      /**
       * @see TemplateOptions#userMetadata(String, String)
       */
      public static AWSEC2TemplateOptions userMetadata(String key, String value) {
         AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
         return AWSEC2TemplateOptions.class.cast(options.userMetadata(key, value));
      }

      public static AWSEC2TemplateOptions blockUntilRunning(boolean blockUntilRunning) {
         AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
         return options.blockUntilRunning(blockUntilRunning);
      }

      /**
       * @see TemplateOptions#nodeNames(Iterable)
       */
      public static AWSEC2TemplateOptions nodeNames(Iterable<String> nodeNames) {
         AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
         return AWSEC2TemplateOptions.class.cast(options.nodeNames(nodeNames));
      }

      /**
       * @see TemplateOptions#networks(Iterable)
       */
      public static AWSEC2TemplateOptions networks(Iterable<String> networks) {
         AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
         return AWSEC2TemplateOptions.class.cast(options.networks(networks));
      }
   }

   // methods that only facilitate returning the correct object type

   /**
    * {@inheritDoc}
    */
   @Override
   public AWSEC2TemplateOptions blockDeviceMappings(Iterable<? extends BlockDeviceMapping> blockDeviceMappings) {
      return AWSEC2TemplateOptions.class.cast(super.blockDeviceMappings(blockDeviceMappings));
   }

   /**
    * {@inheritDoc}
    */
   @Override
   public AWSEC2TemplateOptions userMetadata(Map<String, String> userMetadata) {
      return AWSEC2TemplateOptions.class.cast(super.userMetadata(userMetadata));
   }

   /**
    * {@inheritDoc}
    */
   @Override
   public AWSEC2TemplateOptions userMetadata(String key, String value) {
      return AWSEC2TemplateOptions.class.cast(super.userMetadata(key, value));
   }

   /**
    * {@inheritDoc}
    */
   @Override
   public AWSEC2TemplateOptions nodeNames(Iterable<String> nodeNames) {
      return AWSEC2TemplateOptions.class.cast(super.nodeNames(nodeNames));
   }

   /**
    * {@inheritDoc}
    */
   @Override
   public AWSEC2TemplateOptions networks(Iterable<String> networks) {
      return AWSEC2TemplateOptions.class.cast(super.networks(networks));
   }

   /**
    * {@inheritDoc}
    */
   @Override
   public AWSEC2TemplateOptions keyPair(String keyPair) {
      return AWSEC2TemplateOptions.class.cast(super.keyPair(keyPair));
   }

   /**
    * {@inheritDoc}
    */

   @Override
   public AWSEC2TemplateOptions mapEBSSnapshotToDeviceName(String deviceName, String snapshotId, Integer sizeInGib,
         boolean deleteOnTermination) {
      return AWSEC2TemplateOptions.class.cast(super.mapEBSSnapshotToDeviceName(deviceName, snapshotId, sizeInGib,
            deleteOnTermination));
   }

   /**
    * {@inheritDoc}
    */
   @Override
   public AWSEC2TemplateOptions mapEphemeralDeviceToDeviceName(String deviceName, String virtualName) {
      return AWSEC2TemplateOptions.class.cast(super.mapEphemeralDeviceToDeviceName(deviceName, virtualName));
   }

   /**
    * {@inheritDoc}
    */
   @Override
   public AWSEC2TemplateOptions mapNewVolumeToDeviceName(String deviceName, int sizeInGib, boolean deleteOnTermination) {
      return AWSEC2TemplateOptions.class.cast(super
            .mapNewVolumeToDeviceName(deviceName, sizeInGib, deleteOnTermination));
   }

   /**
    * {@inheritDoc}
    */
   @Override
   public AWSEC2TemplateOptions noKeyPair() {
      return AWSEC2TemplateOptions.class.cast(super.noKeyPair());
   }

   /**
    * {@inheritDoc}
    */
   @Override
   public AWSEC2TemplateOptions securityGroups(Iterable<String> groupIds) {
      return AWSEC2TemplateOptions.class.cast(super.securityGroups(groupIds));
   }

   /**
    * {@inheritDoc}
    */
   @Override
   public AWSEC2TemplateOptions securityGroups(String... groupIds) {
      return AWSEC2TemplateOptions.class.cast(super.securityGroups(groupIds));
   }

   /**
    * {@inheritDoc}
    */
   @Override
   public AWSEC2TemplateOptions unmapDeviceNamed(String deviceName) {
      return AWSEC2TemplateOptions.class.cast(super.unmapDeviceNamed(deviceName));
   }

   /**
    * {@inheritDoc}
    */
   @Override
   public AWSEC2TemplateOptions userData(byte[] unencodedData) {
      return AWSEC2TemplateOptions.class.cast(super.userData(unencodedData));
   }

   /**
    * {@inheritDoc}
    */
   @Override
   public AWSEC2TemplateOptions blockOnPort(int port, int seconds) {
      return AWSEC2TemplateOptions.class.cast(super.blockOnPort(port, seconds));
   }

   /**
    * {@inheritDoc}
    */
   @Override
   public AWSEC2TemplateOptions inboundPorts(int... ports) {
      return AWSEC2TemplateOptions.class.cast(super.inboundPorts(ports));
   }

   /**
    * {@inheritDoc}
    */
   @Override
   public AWSEC2TemplateOptions authorizePublicKey(String publicKey) {
      return AWSEC2TemplateOptions.class.cast(super.authorizePublicKey(publicKey));
   }

   /**
    * {@inheritDoc}
    */
   @Override
   public AWSEC2TemplateOptions installPrivateKey(String privateKey) {
      return AWSEC2TemplateOptions.class.cast(super.installPrivateKey(privateKey));
   }

   /**
    * {@inheritDoc}
    */
   @Override
   public AWSEC2TemplateOptions blockUntilRunning(boolean blockUntilRunning) {
      return AWSEC2TemplateOptions.class.cast(super.blockUntilRunning(blockUntilRunning));
   }

   /**
    * {@inheritDoc}
    */
   @Override
   public AWSEC2TemplateOptions dontAuthorizePublicKey() {
      return AWSEC2TemplateOptions.class.cast(super.dontAuthorizePublicKey());
   }

   /**
    * {@inheritDoc}
    */
   @Override
   public AWSEC2TemplateOptions nameTask(String name) {
      return AWSEC2TemplateOptions.class.cast(super.nameTask(name));
   }

   /**
    * {@inheritDoc}
    */
   @Override
   public AWSEC2TemplateOptions runAsRoot(boolean runAsRoot) {
      return AWSEC2TemplateOptions.class.cast(super.runAsRoot(runAsRoot));
   }

   /**
    * {@inheritDoc}
    */
   @Override
   public AWSEC2TemplateOptions runScript(Statement script) {
      return AWSEC2TemplateOptions.class.cast(super.runScript(script));
   }
   
   /**
    * {@inheritDoc}
    */
   @Override
   public AWSEC2TemplateOptions overrideLoginCredentials(LoginCredentials overridingCredentials) {
      return AWSEC2TemplateOptions.class.cast(super.overrideLoginCredentials(overridingCredentials));
   }

   /**
    * {@inheritDoc}
    */
   @Override
   public AWSEC2TemplateOptions overrideLoginPassword(String password) {
      return AWSEC2TemplateOptions.class.cast(super.overrideLoginPassword(password));
   }

   /**
    * {@inheritDoc}
    */
   @Override
   public AWSEC2TemplateOptions overrideLoginPrivateKey(String privateKey) {
      return AWSEC2TemplateOptions.class.cast(super.overrideLoginPrivateKey(privateKey));
   }

   /**
    * {@inheritDoc}
    */
   @Override
   public AWSEC2TemplateOptions overrideLoginUser(String loginUser) {
      return AWSEC2TemplateOptions.class.cast(super.overrideLoginUser(loginUser));
   }

   /**
    * {@inheritDoc}
    */
   @Override
   public AWSEC2TemplateOptions overrideAuthenticateSudo(boolean authenticateSudo) {
      return AWSEC2TemplateOptions.class.cast(super.overrideAuthenticateSudo(authenticateSudo));
   }

   /**
    * @return placementGroup to use when running the instance or null, to
    *         generate a placementGroup.
    */
   public String getPlacementGroup() {
      return placementGroup;
   }

   /**
    * @return true (default) if we are supposed to use a placementGroup
    */
   public boolean shouldAutomaticallyCreatePlacementGroup() {
      return !noPlacementGroup;
   }

   /**
    * @return true (default) if we are supposed to enable cloudwatch
    */
   public boolean isMonitoringEnabled() {
      return monitoringEnabled;
   }

   /**
    * @return subnetId to use when running the instance or null.
    */
   public String getSubnetId() {
      return subnetId;
   }

   /**
    * @return maximum spot price or null.
    */
   public Float getSpotPrice() {
      return spotPrice;
   }

   /**
    * @return options for controlling spot instance requests.
    */
   public RequestSpotInstancesOptions getSpotOptions() {
      return spotOptions;
   }

   /**
    * The Amazon resource name (ARN) of the IAM Instance Profile (IIP) to associate with the instance.
    * 
    * @see org.jclouds.aws.ec2.options.AWSRunInstancesOptions#withIAMInstanceProfileArn(String)
    */
   @SinceApiVersion("2012-06-01")
   public String getIAMInstanceProfileArn() {
      return iamInstanceProfileArn;
   }

   /**
    * The name of the IAM Instance Profile (IIP) to associate with the instance.
    * 
    * @see org.jclouds.aws.ec2.options.AWSRunInstancesOptions#withIAMInstanceProfileName(String)
    */
   @SinceApiVersion("2012-06-01")
   public String getIAMInstanceProfileName() {
      return iamInstanceProfileName;
   }

   public String getPrivateIpAddress() {
      return privateIpAddress;
   }
}
