@Test(enabled = true)
  public void testCreateTemplate() throws Exception {
    Zone zone = Iterables.getFirst(client.getZoneClient().listZones(), null);
    assertNotNull(zone);
    Iterable<Network> networks =
        client
            .getNetworkClient()
            .listNetworks(ListNetworksOptions.Builder.zoneId(zone.getId()).isDefault(true));
    networks =
        Iterables.filter(
            networks,
            new Predicate<Network>() {
              @Override
              public boolean apply(@Nullable Network network) {
                return network != null && network.getState().equals("Implemented");
              }
            });
    assertEquals(Iterables.size(networks), 1);
    Network network = Iterables.getOnlyElement(networks, null);
    assertNotNull(network);

    // Create a VM and stop it
    Long templateId = (imageId != null && !"".equals(imageId)) ? new Long(imageId) : null;
    vmForCreation =
        VirtualMachineClientLiveTest.createVirtualMachineInNetwork(
            network, templateId, client, jobComplete, virtualMachineRunning);
    assertTrue(
        jobComplete.apply(
            client.getVirtualMachineClient().stopVirtualMachine(vmForCreation.getId())),
        vmForCreation.toString());

    // Work out the VM's volume
    Set<Volume> volumes =
        client
            .getVolumeClient()
            .listVolumes(ListVolumesOptions.Builder.virtualMachineId(vmForCreation.getId()));
    assertEquals(volumes.size(), 1);
    Volume volume = Iterables.getOnlyElement(volumes);

    // Create a template
    CreateTemplateOptions options = CreateTemplateOptions.Builder.volumeId(volume.getId());
    AsyncCreateResponse response =
        client
            .getTemplateClient()
            .createTemplate(
                TemplateMetadata.builder()
                    .name(prefix + "-createTemplate")
                    .osTypeId(vmForCreation.getGuestOSId())
                    .displayText("jclouds live testCreateTemplate")
                    .build(),
                options);
    assertTrue(jobComplete.apply(response.getJobId()), vmForCreation.toString());
    createdTemplate =
        client.getTemplateClient().getTemplateInZone(response.getId(), vmForCreation.getZoneId());

    // Assertions
    assertNotNull(createdTemplate);
  }
  protected String runningVM(Set<VirtualMachine> listVirtualMachines) throws Exception {
    for (VirtualMachine vm : listVirtualMachines) {
      if (vm.getState() == State.RUNNING) {
        return vm.getId();
      }
    }

    throw new Exception("Not found the running vm");
  }
  @Test
  public void testWaitForVirtualMachineToBeExpunged() {
    VirtualMachine virtualMachine = VirtualMachine.builder().id("229").build();
    expect(virtualMachineClient.getVirtualMachine(virtualMachine.getId())).andReturn(null);

    replay(client, virtualMachineClient);
    assertTrue(new VirtualMachineExpunged(client).apply(virtualMachine));
    verify(client, virtualMachineClient);
  }
  private void randomRebootVirtualMachine() throws InterruptedException {
    CommonUtil.beforeMsg();

    VirtualMachine next = client.getVirtualMachineClient().listVirtualMachines().iterator().next();
    String vmId = next.getId();
    System.out.println("### Reboot VirtualMachine : Target VM ID : " + vmId);
    String jobId = client.getVirtualMachineClient().rebootVirtualMachine(vmId);

    jobStatus(jobId);
  }
  @Test
  public void testNoRemovedYet() {
    VirtualMachine virtualMachine = VirtualMachine.builder().id("229").build();
    expect(virtualMachineClient.getVirtualMachine(virtualMachine.getId()))
        .andReturn(virtualMachine);

    replay(client, virtualMachineClient);
    assertFalse(new VirtualMachineExpunged(client).apply(virtualMachine));
    verify(client, virtualMachineClient);
  }
  private void stopVirtaulMachine() throws Exception {
    CommonUtil.beforeMsg();

    VirtualMachine virtualMachine = client.getVirtualMachineClient().getVirtualMachine(runningVM());
    String name = virtualMachine.getName();
    String vmId = virtualMachine.getId();
    System.out.println("VM ID : " + vmId + ", VM Name : " + name);
    String jobId = client.getVirtualMachineClient().stopVirtualMachine(vmId);

    jobStatus(jobId);
  }
  protected String stoppedVM() throws Exception {
    Set<VirtualMachine> listVirtualMachines =
        client.getVirtualMachineClient().listVirtualMachines();
    for (VirtualMachine vm : listVirtualMachines) {
      if (vm.getState() == State.STOPPED) {
        return vm.getId();
      }
    }

    throw new Exception("Not found the stopped vm");
  }
 @AfterGroups(groups = "live")
 protected void tearDown() {
   if (vmForCreation != null) {
     assertTrue(
         jobComplete.apply(
             client.getVirtualMachineClient().stopVirtualMachine(vmForCreation.getId())),
         vmForCreation.toString());
     assertTrue(
         jobComplete.apply(
             client.getVirtualMachineClient().destroyVirtualMachine(vmForCreation.getId())),
         vmForCreation.toString());
     assertTrue(virtualMachineDestroyed.apply(vmForCreation));
   }
   if (vmForRegistration != null) {
     assertTrue(
         jobComplete.apply(
             client.getVirtualMachineClient().stopVirtualMachine(vmForRegistration.getId())),
         vmForRegistration.toString());
     assertTrue(
         jobComplete.apply(
             client.getVirtualMachineClient().destroyVirtualMachine(vmForRegistration.getId())),
         vmForRegistration.toString());
     assert virtualMachineDestroyed.apply(vmForRegistration);
   }
   if (createdTemplate != null) {
     AsyncCreateResponse deleteJob =
         client.getTemplateClient().deleteTemplate(createdTemplate.getId());
     assertTrue(jobComplete.apply(deleteJob.getJobId()));
   }
   if (registeredTemplate != null) {
     AsyncCreateResponse deleteJob =
         client.getTemplateClient().deleteTemplate(registeredTemplate.getId());
     assertTrue(jobComplete.apply(deleteJob.getJobId()));
   }
   super.tearDown();
 }
 @AfterGroups(groups = "live")
 protected void tearDown() {
   if (vm != null) {
     assert jobComplete.apply(client.getVirtualMachineClient().destroyVirtualMachine(vm.getId()));
   }
   if (group != null) {
     for (IngressRule rule : group.getIngressRules())
       assert this.jobComplete.apply(
               client.getSecurityGroupClient().revokeIngressRule(rule.getId()))
           : rule;
     client.getSecurityGroupClient().deleteSecurityGroup(group.getId());
     assertEquals(client.getSecurityGroupClient().getSecurityGroup(group.getId()), null);
   }
   super.tearDown();
 }
  @Override
  public NodeMetadata apply(VirtualMachine from) {
    // convert the result object to a jclouds NodeMetadata
    NodeMetadataBuilder builder = new NodeMetadataBuilder();
    builder.ids(from.getId() + "");
    builder.name(from.getName());
    // TODO: in cloudstack 2.2.12, when "name" was set fine on the backend,
    // but wrong API response was returned to the user
    // http://bugs.cloud.com/show_bug.cgi?id=11664
    //
    // we set displayName to the same value as name, but this could be wrong
    // on hosts not started with jclouds
    builder.hostname(from.getDisplayName());
    builder.location(findLocationForVirtualMachine.apply(from));
    builder.group(parseGroupFromName(from.getDisplayName()));
    Image image = findImageForVirtualMachine.apply(from);
    if (image != null) {
      builder.imageId(image.getId());
      builder.operatingSystem(image.getOperatingSystem());
    }

    builder.hardware(
        new HardwareBuilder()
            .ids(from.getServiceOfferingId() + "")
            .name(from.getServiceOfferingName() + "")
            // .tags() TODO
            .processors(ImmutableList.of(new Processor(from.getCpuCount(), from.getCpuSpeed())))
            .ram((int) from.getMemory()) //
            .hypervisor(from.getHypervisor()) //
            .build());

    builder.state(vmStateToNodeState.get(from.getState()));

    Set<String> publicAddresses = newHashSet(), privateAddresses = newHashSet();
    if (from.getIPAddress() != null) {
      boolean isPrivate = isPrivateIPAddress(from.getIPAddress());
      if (isPrivate) {
        privateAddresses.add(from.getIPAddress());
      } else {
        publicAddresses.add(from.getIPAddress());
      }
    }
    for (NIC nic : from.getNICs()) {
      if (nic.getIPAddress() != null) {
        if (isPrivateIPAddress(nic.getIPAddress())) {
          privateAddresses.add(nic.getIPAddress());
        } else {
          publicAddresses.add(nic.getIPAddress());
        }
      }
    }
    try {
      /* Also add to the list of public IPs any public IP address that has a
      forwarding rule that links to this machine */
      Iterables.addAll(
          publicAddresses,
          transform(
              filter(
                  getIPForwardingRulesByVirtualMachine.getUnchecked(from.getId()),
                  new Predicate<IPForwardingRule>() {
                    @Override
                    public boolean apply(@Nullable IPForwardingRule rule) {
                      return !"Deleting".equals(rule.getState());
                    }
                  }),
              new Function<IPForwardingRule, String>() {
                @Override
                public String apply(@Nullable IPForwardingRule rule) {
                  return rule.getIPAddress();
                }
              }));
    } catch (UncheckedExecutionException e) {
      if (Throwables2.getFirstThrowableOfType(e, ResourceNotFoundException.class) == null) {
        Throwables.propagateIfPossible(e.getCause());
        throw e;
      }
    }
    return builder.privateAddresses(privateAddresses).publicAddresses(publicAddresses).build();
  }