private @Nonnull List<String> lookupRecord(DNSRecord record)
      throws CloudException, InternalException {
    APITrace.begin(provider, "DNS.lookupRecord");
    try {
      ProviderContext ctx = provider.getContext();

      if (ctx == null) {
        logger.error("No context exists for this request");
        throw new InternalException("No context exists for this request");
      }
      NovaMethod method = new NovaMethod(provider);
      JSONObject response =
          method.getResource(SERVICE, RESOURCE, record.getProviderZoneId() + "/records", false);

      if (response == null) {
        return null;
      }
      ArrayList<String> ids = new ArrayList<String>();

      try {
        if (response.has("records")) {
          JSONArray list = response.getJSONArray("records");

          for (int i = 0; i < list.length(); i++) {
            JSONObject item = list.getJSONObject(i);

            if (item != null) {
              String n = (item.has("name") ? item.getString("name") : null);
              String id = (item.has("id") ? item.getString("id") : null);

              if (n == null || id == null) {
                continue;
              }
              if (record.getName().equals(n) || record.getName().equals(n + ".")) {
                ids.add(id);
              }
            }
          }
        }
      } catch (JSONException e) {
        logger.error("lookupRecord(): JSON error parsing response: " + e.getMessage());
        e.printStackTrace();
        throw new CloudException(
            CloudErrorType.COMMUNICATION, 200, "invalidResponse", "JSON error parsing " + response);
      }
      return ids;
    } finally {
      APITrace.end();
    }
  }
  @Override
  public @Nonnull Iterable<DNSRecord> listDnsRecords(
      @Nonnull String providerDnsZoneId, @Nullable DNSRecordType forType, @Nullable String name)
      throws CloudException, InternalException {
    APITrace.begin(provider, "DNS.listDnsRecords");
    try {
      DNSZone zone = getDnsZone(providerDnsZoneId);

      if (zone == null) {
        throw new CloudException("No such zone: " + providerDnsZoneId);
      }
      ProviderContext ctx = provider.getContext();

      if (ctx == null) {
        logger.error("No context exists for this request");
        throw new InternalException("No context exists for this request");
      }
      NovaMethod method = new NovaMethod(provider);
      JSONObject response =
          method.getResource(SERVICE, RESOURCE, providerDnsZoneId + "/records", false);

      if (response == null) {
        return Collections.emptyList();
      }
      ArrayList<DNSRecord> records = new ArrayList<DNSRecord>();
      try {
        int count = 0, total = 0;

        if (response.has("totalEntries")) {
          total = response.getInt("totalEntries");
        }
        while (response != null) {
          int current = 0;

          if (response.has("records")) {
            JSONArray list = response.getJSONArray("records");

            current = list.length();
            count += current;
            for (int i = 0; i < list.length(); i++) {
              DNSRecord record = toRecord(ctx, zone, list.getJSONObject(i));

              if (record != null) {
                if (forType == null || forType.equals(record.getType())) {
                  if (name == null || name.equals(record.getName())) {
                    records.add(record);
                  }
                }
              }
            }
          }
          response = null;
          if (current > 0 && count < total) {
            response =
                method.getResource(
                    SERVICE, RESOURCE, providerDnsZoneId + "/records?offset=" + count, false);
          }
        }
      } catch (JSONException e) {
        logger.error("listDnsRecords(): JSON error parsing response: " + e.getMessage());
        e.printStackTrace();
        throw new CloudException(
            CloudErrorType.COMMUNICATION, 200, "invalidResponse", "JSON error parsing " + response);
      }
      return records;
    } finally {
      APITrace.end();
    }
  }