   public RunInstancesResponseVCloud runInstances(RunInstancesRequestVCloud vCloudRequest) {
      String vAppTemplateId = vCloudRequest.getvAppTemplateId();
      log.info("RunInstances vAppTemplateId: " + vAppTemplateId);
      VAppTemplate vAppTemplate = vAppTemplateApi.get(vAppTemplateId);
      if (vAppTemplate == null) {
         throw new EC2ServiceException("VAppTemplate not found for: " + vAppTemplateId);
      }
      Vdc vdc = getVDC();
      Set<Reference> availableNetworkRefs = vdc.getAvailableNetworks();
      if (availableNetworkRefs.isEmpty()) {
         throw new EC2ServiceException("No Networks in vdc to compose vapp");
      }
      String vcdNetwork = env.getProperty(CinderellaConfig.VCD_NETWORK_KEY);
      final Reference parentNetwork = FluentIterable.from(vdc.getAvailableNetworks())
            .filter(ReferencePredicates.<Reference>nameEquals(vcdNetwork))
            .first()
            .get();
      NetworkConfigSection templateNetworkConfigSection = vAppTemplateApi.getNetworkConfigSection(vAppTemplateId);
      Set<VAppNetworkConfiguration> vAppNetworkConfigurations = new HashSet<VAppNetworkConfiguration>();
      for (VAppNetworkConfiguration templateVAppNetworkConfig : templateNetworkConfigSection.getNetworkConfigs()) {
         vAppNetworkConfigurations.add(
               VAppNetworkConfiguration.builder()
                     .networkName(templateVAppNetworkConfig.getNetworkName())
                     .configuration(
                           NetworkConfiguration.builder()
                                 .parentNetwork(parentNetwork)
                                 .fenceMode(Network.FenceMode.BRIDGED)
                                 .build()
                     )
                     .isDeployed(true)
                     .build()
         );
      }
      NetworkConfigSection networkConfigSection = NetworkConfigSection
            .builder()
            .info("Configuration parameters for logical networks")
            .networkConfigs(ImmutableSet.copyOf(vAppNetworkConfigurations))
            .build();
      InstantiationParams instantiationParams = InstantiationParams.builder()
            .sections(ImmutableSet.of(networkConfigSection))
            .build();
      InstantiateVAppTemplateParams instantiateVAppTemplateParams = InstantiateVAppTemplateParams.builder()
            .name(name("cinderella-" + vCloudDirectorApi.getCurrentSession().getUser()))
            .deploy()
            .notDeploy()
            .notPowerOn()
            .description("Created by Cinderella")
            .instantiationParams(instantiationParams)
            .source(vAppTemplate.getHref())
            .build();
      String vdcUrn = vdc.getId();
      VApp instantiatedVApp = vdcApi.instantiateVApp(vdcUrn, instantiateVAppTemplateParams);
      Task instantiationTask = Iterables.getFirst(instantiatedVApp.getTasks(), null);
      boolean instantiationSuccess = retryTaskSuccessLong.apply(instantiationTask);
      if (instantiationSuccess) {
         log.info("successfully instantiated vApp");
         VApp vapp = vAppApi.get(instantiatedVApp.getHref());
         List<Vm> vms = vapp.getChildren().getVms();
         for (Vm vm : vms) {
            NetworkConnectionSection oldSection = vmApi.getNetworkConnectionSection(vm.getHref());
            NetworkConnectionSection newNetworkConnectionSection = oldSection.toBuilder()
                  .primaryNetworkConnectionIndex(0)
                  .networkConnections(ImmutableSet.of(NetworkConnection.builder()
                        .network(parentNetwork.getName())
                        .networkConnectionIndex(0)
                        .ipAddressAllocationMode(NetworkConnection.IpAddressAllocationMode.POOL)
                        .isConnected(true)
                        .build()))
                  .build();
            Task editNetworkConnectionSectionTask = vmApi.editNetworkConnectionSection(vm.getHref(), newNetworkConnectionSection);
            boolean updateVmNetworkSuccess = retryTaskSuccessLong.apply(editNetworkConnectionSectionTask);
            if (updateVmNetworkSuccess) {
               log.info("successfully updated " + vm.getId() + " network config");
            }
         }
         Task powerOnTask = vAppApi.powerOn(instantiatedVApp.getHref());
         boolean powerOnSuccess = retryTaskSuccessLong.apply(powerOnTask);
         if (powerOnSuccess) {
            log.info("successfully powered on vApp");
         }
      }
      VApp vapp = vAppApi.get(instantiatedVApp.getHref());
      Set<String> ips = VCloudDirectorComputeUtils.getIpsFromVm(vapp.getChildren().getVms().get(0));
      String publicIpAddress = null;
      for (String ip : ips) {
         if (!InetAddresses2.isPrivateIPAddress(ip)) {
            publicIpAddress = ip;
         }
      }
      log.info("public ip: " + publicIpAddress);
      instantiatedVApp = vAppApi.get(instantiatedVApp.getId());
      if (instantiationSuccess && (null != vCloudRequest.getKeyName() && vCloudRequest.getKeyName().length() > 0)) {
          Vm vm = Iterables.getFirst(instantiatedVApp.getChildren().getVms(), null);
          LoginCredentials creds = LoginCredentials.builder(VCloudDirectorComputeUtils.getCredentialsFrom(vm))
                  .identity("root")
                  .build();
          NetworkConnectionSection nets = vmApi.getNetworkConnectionSection(vm.getId());
          String ipaddress = null;
          for (NetworkConnection net : nets.getNetworkConnections()) {
              ipaddress = net.getIpAddress();
          }
          System.out.println("Credentials: " + creds.getUser()  + " : " +  creds.getPassword() + " : " + creds.getOptionalPrivateKey().or("NONE"));
          Media keyPairsContainer = null;
          Optional<Media> optionalKeyPairsContainer = null;
          optionalKeyPairsContainer = FluentIterable
                .from(findAllEmptyMediaInOrg().toImmutableList())
                .first();
          if (optionalKeyPairsContainer.isPresent()) {
              String key = null;
              keyPairsContainer = optionalKeyPairsContainer.get();
              vCloudRequest.getKeyName();
              Map<String, String> sshKey;
              for (MetadataEntry entry : mediaApi.getMetadataApi(keyPairsContainer.getId()).get().getMetadataEntries()) {
                  sshKey = json.fromJson(entry.getValue(), new TypeToken<Map<String, String>>() {
                  }.getType());
                  if (vCloudRequest.getKeyName().equalsIgnoreCase(sshKey.get("keyName"))) {
                      key = sshKey.get("publicKey");
                  }
              }
              SshClient client = new SshjSshClient(BackoffLimitedRetryHandler.INSTANCE, HostAndPort.fromParts(ipaddress, 22), creds, 30000);
              ImmutableList.Builder<String> keys= ImmutableList.builder();
              keys.add(key);
              AuthorizeRSAPublicKeys authrsa = new AuthorizeRSAPublicKeys(keys.build());
              client.connect();
              ExecResponse sshresponse = client.exec(authrsa.render(OsFamily.UNIX));
              if (sshresponse.getExitStatus() != 0) {
                  log.error(sshresponse.getError());
              }
              client.disconnect();
          }
       }
      RunInstancesResponseVCloud response = new RunInstancesResponseVCloud();
      response.setVmId(vapp.getChildren().getVms().get(0).getId());
      return response;
   }

   public RunInstancesResponseVCloud runInstances(RunInstancesRequestVCloud vCloudRequest) {
      String vAppTemplateId = vCloudRequest.getvAppTemplateId();
      log.info("RunInstances vAppTemplateId: " + vAppTemplateId);
      VAppTemplate vAppTemplate = vAppTemplateApi.get(vAppTemplateId);
      if (vAppTemplate == null) {
         throw new EC2ServiceException("VAppTemplate not found for: " + vAppTemplateId);
      }
      Vdc vdc = getVDC();
      Set<Reference> availableNetworkRefs = vdc.getAvailableNetworks();
      if (availableNetworkRefs.isEmpty()) {
         throw new EC2ServiceException("No Networks in vdc to compose vapp");
      }
      String vcdNetwork = env.getProperty(CinderellaConfig.VCD_NETWORK_KEY);
      final Reference parentNetwork = FluentIterable.from(vdc.getAvailableNetworks())
            .filter(ReferencePredicates.<Reference>nameEquals(vcdNetwork))
            .first()
            .get();
      NetworkConfigSection templateNetworkConfigSection = vAppTemplateApi.getNetworkConfigSection(vAppTemplateId);
      Set<VAppNetworkConfiguration> vAppNetworkConfigurations = new HashSet<VAppNetworkConfiguration>();
      for (VAppNetworkConfiguration templateVAppNetworkConfig : templateNetworkConfigSection.getNetworkConfigs()) {
         vAppNetworkConfigurations.add(
               VAppNetworkConfiguration.builder()
                     .networkName(templateVAppNetworkConfig.getNetworkName())
                     .configuration(
                           NetworkConfiguration.builder()
                                 .parentNetwork(parentNetwork)
                                 .fenceMode(Network.FenceMode.BRIDGED)
                                 .build()
                     )
                     .isDeployed(true)
                     .build()
         );
      }
      NetworkConfigSection networkConfigSection = NetworkConfigSection
            .builder()
            .info("Configuration parameters for logical networks")
            .networkConfigs(ImmutableSet.copyOf(vAppNetworkConfigurations))
            .build();
      InstantiationParams instantiationParams = InstantiationParams.builder()
            .sections(ImmutableSet.of(networkConfigSection))
            .build();
      InstantiateVAppTemplateParams instantiateVAppTemplateParams = InstantiateVAppTemplateParams.builder()
            .name(name("cinderella-" + vCloudDirectorApi.getCurrentSession().getUser()))
            .notDeploy()
            .notPowerOn()
            .description("Created by Cinderella")
            .instantiationParams(instantiationParams)
            .source(vAppTemplate.getHref())
            .build();
      String vdcUrn = vdc.getId();
      VApp instantiatedVApp = vdcApi.instantiateVApp(vdcUrn, instantiateVAppTemplateParams);
      Task instantiationTask = Iterables.getFirst(instantiatedVApp.getTasks(), null);
      boolean instantiationSuccess = retryTaskSuccessLong.apply(instantiationTask);
      if (instantiationSuccess) {
         log.info("successfully instantiated vApp");
         VApp vapp = vAppApi.get(instantiatedVApp.getHref());
         List<Vm> vms = vapp.getChildren().getVms();
         for (Vm vm : vms) {
            NetworkConnectionSection oldSection = vmApi.getNetworkConnectionSection(vm.getHref());
            NetworkConnectionSection newNetworkConnectionSection = oldSection.toBuilder()
                  .primaryNetworkConnectionIndex(0)
                  .networkConnections(ImmutableSet.of(NetworkConnection.builder()
                        .network(parentNetwork.getName())
                        .networkConnectionIndex(0)
                        .ipAddressAllocationMode(NetworkConnection.IpAddressAllocationMode.POOL)
                        .isConnected(true)
                        .build()))
                  .build();
            Task editNetworkConnectionSectionTask = vmApi.editNetworkConnectionSection(vm.getHref(), newNetworkConnectionSection);
            boolean updateVmNetworkSuccess = retryTaskSuccessLong.apply(editNetworkConnectionSectionTask);
            if (updateVmNetworkSuccess) {
               log.info("successfully updated " + vm.getId() + " network config");
            }
         }
         Task powerOnTask = vAppApi.powerOn(instantiatedVApp.getHref());
         boolean powerOnSuccess = retryTaskSuccessLong.apply(powerOnTask);
         if (powerOnSuccess) {
            log.info("successfully powered on vApp");
         }
      }
      VApp vapp = vAppApi.get(instantiatedVApp.getHref());
      Set<String> ips = VCloudDirectorComputeUtils.getIpsFromVm(vapp.getChildren().getVms().get(0));
      String publicIpAddress = null;
      for (String ip : ips) {
         if (!InetAddresses2.isPrivateIPAddress(ip)) {
            publicIpAddress = ip;
         }
      }
      log.info("public ip: " + publicIpAddress);
      instantiatedVApp = vAppApi.get(instantiatedVApp.getId());
      if (instantiationSuccess && (null != vCloudRequest.getKeyName() && vCloudRequest.getKeyName().length() > 0)) {
          Vm vm = Iterables.getFirst(instantiatedVApp.getChildren().getVms(), null);
          LoginCredentials creds = LoginCredentials.builder(VCloudDirectorComputeUtils.getCredentialsFrom(vm))
                  .identity("root")
                  .build();
          NetworkConnectionSection nets = vmApi.getNetworkConnectionSection(vm.getId());
          String ipaddress = null;
          for (NetworkConnection net : nets.getNetworkConnections()) {
              ipaddress = net.getIpAddress();
          }
          System.out.println("Credentials: " + creds.getUser()  + " : " +  creds.getPassword() + " : " + creds.getOptionalPrivateKey().or("NONE"));
          Media keyPairsContainer = null;
          Optional<Media> optionalKeyPairsContainer = null;
          optionalKeyPairsContainer = FluentIterable
                .from(findAllEmptyMediaInOrg().toImmutableList())
                .first();
          if (optionalKeyPairsContainer.isPresent()) {
              String key = null;
              keyPairsContainer = optionalKeyPairsContainer.get();
              vCloudRequest.getKeyName();
              Map<String, String> sshKey;
              for (MetadataEntry entry : mediaApi.getMetadataApi(keyPairsContainer.getId()).get().getMetadataEntries()) {
                  sshKey = json.fromJson(entry.getValue(), new TypeToken<Map<String, String>>() {
                  }.getType());
                  if (vCloudRequest.getKeyName().equalsIgnoreCase(sshKey.get("keyName"))) {
                      key = sshKey.get("publicKey");
                  }
              }
              SshClient client = new SshjSshClient(BackoffLimitedRetryHandler.INSTANCE, HostAndPort.fromParts(ipaddress, 22), creds, 30000);
              ImmutableList.Builder<String> keys= ImmutableList.builder();
              keys.add(key);
              AuthorizeRSAPublicKeys authrsa = new AuthorizeRSAPublicKeys(keys.build());
              client.connect();
              ExecResponse sshresponse = client.exec(authrsa.render(OsFamily.UNIX));
              if (sshresponse.getExitStatus() != 0) {
                  log.error(sshresponse.getError());
              }
              client.disconnect();
          }
       }
      RunInstancesResponseVCloud response = new RunInstancesResponseVCloud();
      response.setVmId(vapp.getChildren().getVms().get(0).getId());
      return response;
   }
