/**
	 * @param  $instanceName
	 * @param  $image
	 * @param  $key
	 * @param  $instanceType
	 * @param  $availabilityZone
	 * @param  $groups
	 * @return null|OpenStackNovaInstance
	 */
	function createInstance( $instanceName, $image, $key, $instanceType, $availabilityZone, $groups ) {
		global $wgOpenStackManagerInstanceUserData;

		$options = array();
		if ( $key ) {
			$options['KeyName'] = $key;
		}
		$options['InstanceType'] = $instanceType;
		$options['Placement.AvailabilityZone'] = $availabilityZone;
		$options['DisplayName'] = $instanceName;
		if ( $wgOpenStackManagerInstanceUserData ) {
			$random_hash = md5(date('r', time()));
			$endl = $this->getLineEnding();
			$boundary = '===============' . $random_hash .'==';
			$userdata = 'Content-Type: multipart/mixed; boundary="' . $boundary .'"' . $endl;
			$userdata .= 'MIME-Version: 1.0' . $endl;
			$boundary = '--' . $boundary;
			$userdata .= $endl;
			$userdata .= $boundary;
			if ( $wgOpenStackManagerInstanceUserData['cloud-config'] ) {
				$userdata .= $endl . $this->getAttachmentMime( Spyc::YAMLDump( $wgOpenStackManagerInstanceUserData['cloud-config'] ), 'text/cloud-config', 'cloud-config.txt' );
				$userdata .= $endl . $boundary;
			}
			if ( $wgOpenStackManagerInstanceUserData['scripts'] ) {
				foreach ( $wgOpenStackManagerInstanceUserData['scripts'] as $scriptname => $script ) {
					wfSuppressWarnings();
					$stat = stat( $script );
					wfRestoreWarnings();
					if ( ! $stat ) {
						continue;
					}
					$scripttext = file_get_contents( $script );
					$userdata .= $endl . $this->getAttachmentMime( $scripttext, 'text/x-shellscript', $scriptname );
					$userdata .= $endl . $boundary;
				}
			}
			if ( $wgOpenStackManagerInstanceUserData['upstarts'] ) {
				foreach ( $wgOpenStackManagerInstanceUserData['upstarts'] as $upstartname => $upstart ) {
					wfSuppressWarnings();
					$stat = stat( $upstart );
					wfRestoreWarnings();
					if ( ! $stat ) {
						continue;
					}
					$upstarttext = file_get_contents( $upstart );
					$userdata .= $endl . $this->getAttachmentMime( $upstarttext, 'text/upstart-job', $upstartname );
					$userdata .= $endl . $boundary;
				}
			}
			$userdata .= '--';
			$options['UserData'] = base64_encode( $userdata );
		}
		if ( count( $groups ) > 1 ) {
			$options['SecurityGroup'] = $groups;
		} elseif ( count( $groups ) == 1 ) {
			$options['SecurityGroup'] = $groups[0];
		}
		# 1, 1 is min and max number of instances to create.
		# We never want to make more than one at a time.
		$response = $this->novaConnection->run_instances( $image, 1, 1, $options );
		if ( ! $response->isOK() ) {
			return null;
		}
		$instance = new OpenStackNovaInstance( $response->body );
		$instanceId = $instance->getInstanceId();
		$this->instances["$instanceId"] = $instance;

		return $instance;
	}
 /**
  * @return OpenStackNovaInstance[]
  */
 function getInstances()
 {
     $instancesarr = array();
     $ret = $this->restCall('compute', '/servers/detail', 'GET');
     $instances = self::_get_property($ret['body'], 'servers');
     if (!$instances) {
         return $instancesarr;
     }
     foreach ($instances as $instance) {
         $instance = new OpenStackNovaInstance($instance, $this->getRegion(), true);
         $id = $instance->getInstanceOSId();
         $instancesarr[$id] = $instance;
     }
     return $instancesarr;
 }