# File lib/ec2/ec2.rb, line 533
    def launch_instances(image_id, options={})
      @logger.info("Launching instance of image #{image_id} for #{@aws_access_key_id}, " +
                       "key: #{options[:key_name]}, groups: #{(options[:group_ids]).to_a.join(',')}")
      # careful: keyName and securityGroups may be nil
      params = hash_params('SecurityGroup', options[:group_ids].to_a)
      params.update({'ImageId'        => image_id,
                     'MinCount'       => (options[:min_count] || 1).to_s,
                     'MaxCount'       => (options[:max_count] || 1).to_s,
                     'AddressingType' => options[:addressing_type] || DEFAULT_ADDRESSING_TYPE,
                     'InstanceType'   => options[:instance_type] || DEFAULT_INSTANCE_TYPE})
      # optional params
      params['KeyName'] = options[:key_name] unless Aws::Utils.blank?(options[:key_name])
      params['KernelId'] = options[:kernel_id] unless Aws::Utils.blank?(options[:kernel_id])
      params['RamdiskId'] = options[:ramdisk_id] unless Aws::Utils.blank?(options[:ramdisk_id])
      params['Placement.AvailabilityZone'] = options[:availability_zone] unless Aws::Utils.blank?(options[:availability_zone])
      params['BlockDeviceMappings'] = options[:block_device_mappings] unless Aws::Utils.blank?(options[:block_device_mappings])
      params['Monitoring.Enabled'] = options[:monitoring_enabled] unless Aws::Utils.blank?(options[:monitoring_enabled])
      params['SubnetId'] = options[:subnet_id] unless Aws::Utils.blank?(options[:subnet_id])
      params['AdditionalInfo'] = options[:additional_info] unless Aws::Utils.blank?(options[:additional_info])
      params['DisableApiTermination'] = options[:disable_api_termination].to_s unless options[:disable_api_termination].nil?
      params['InstanceInitiatedShutdownBehavior'] = options[:instance_initiated_shutdown_behavior] unless Aws::Utils.blank?(options[:instance_initiated_shutdown_behavior])
      unless Aws::Utils.blank?(options[:user_data])
        options[:user_data].strip!
        # Do not use CGI::escape(encode64(...)) as it is done in Amazons EC2 library.
        # Amazon 169.254.169.254 does not like escaped symbols!
        # And it doesn't like "\n" inside of encoded string! Grrr....
        # Otherwise, some of UserData symbols will be lost...
        params['UserData'] = Base64.encode64(options[:user_data]).delete("\n").strip unless Aws::Utils.blank?(options[:user_data])
      end
      unless Aws::Utils.blank?(options[:block_device_mappings])
        options[:block_device_mappings].size.times do |n|
          if options[:block_device_mappings][n][:virtual_name]
            params["BlockDeviceMapping.#{n+1}.VirtualName"] = options[:block_device_mappings][n][:virtual_name] 
          end
          if options[:block_device_mappings][n][:device_name]
            params["BlockDeviceMapping.#{n+1}.DeviceName"] = options[:block_device_mappings][n][:device_name]  
          end
          if options[:block_device_mappings][n][:ebs_snapshot_id]
            params["BlockDeviceMapping.#{n+1}.Ebs.SnapshotId"] = options[:block_device_mappings][n][:ebs_snapshot_id]  
          end
        end
      end
      link      = generate_request("RunInstances", params)
      #debugger
      instances = request_info(link, QEc2DescribeInstancesParser.new(:logger => @logger))
      get_desc_instances(instances)
    rescue Exception
      on_exception
    end