@Override
 @Unwrap(depth = 2)
 public Set<VirtualMachine> expected() {
   return ImmutableSet.of(
       VirtualMachine.builder()
           .id(54)
           .name("i-3-54-VM")
           .displayName("i-3-54-VM")
           .account("adrian")
           .domainId(1)
           .domain("ROOT")
           .created(
               new SimpleDateFormatDateService()
                   .iso8601SecondsDateParse("2011-02-16T14:28:37-0800"))
           .state(VirtualMachine.State.STARTING)
           .isHAEnabled(false)
           .zoneId(1)
           .zoneName("San Jose 1")
           .templateId(2)
           .templateName("CentOS 5.3(64-bit) no GUI (XenServer)")
           .templateDisplayText("CentOS 5.3(64-bit) no GUI (XenServer)")
           .passwordEnabled(false)
           .serviceOfferingId(1)
           .serviceOfferingName("Small Instance")
           .cpuCount(1)
           .cpuSpeed(500)
           .memory(512)
           .guestOSId(11)
           .rootDeviceId(0)
           .rootDeviceType("NetworkFilesystem")
           .jobId(63l)
           .jobStatus(0)
           .nics(
               ImmutableSet.of(
                   NIC.builder()
                       .id(72)
                       .networkId(204)
                       .netmask("255.255.255.0")
                       .gateway("10.1.1.1")
                       .IPAddress("10.1.1.18")
                       .trafficType(TrafficType.GUEST)
                       .guestIPType(GuestIPType.VIRTUAL)
                       .isDefault(true)
                       .build()))
           .hypervisor("XenServer")
           .build());
 }
  @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();
  }