private @Nullable DNSRecord toRecord(
      @SuppressWarnings("UnusedParameters") @Nonnull ProviderContext ctx,
      @Nonnull DNSZone zone,
      @Nullable JSONObject json)
      throws CloudException, InternalException {
    if (json == null) {
      return null;
    }
    try {
      String recordId = (json.has("id") ? json.getString("id") : null);

      if (recordId == null) {
        return null;
      }
      String name = (json.has("name") ? json.getString("name") : null);

      if (name == null) {
        return null;
      }
      if (name.endsWith(zone.getDomainName())) {
        name = name + ".";
      }
      DNSRecordType recordType = DNSRecordType.A;
      String type = (json.has("type") ? json.getString("type") : null);

      if (type != null) {
        recordType = DNSRecordType.valueOf(type.toUpperCase());
      }
      String data = (json.has("data") ? json.getString("data") : null);
      int ttl = (json.has("ttl") ? json.getInt("ttl") : 3600);

      DNSRecord record = new DNSRecord();

      record.setName(name);
      record.setProviderZoneId(zone.getProviderDnsZoneId());
      record.setTtl(ttl);
      record.setType(recordType);
      record.setValues(data == null ? new String[0] : new String[] {data});

      return record;
    } catch (JSONException e) {
      throw new CloudException(e);
    }
  }
  @Override
  public @Nonnull DNSRecord addDnsRecord(
      @Nonnull String providerDnsZoneId,
      @Nonnull DNSRecordType recordType,
      @Nonnull String name,
      @Nonnegative int ttl,
      @Nonnull String... values)
      throws CloudException, InternalException {
    APITrace.begin(provider, "DNS.addDnsRecord");
    try {
      DNSZone zone = getDnsZone(providerDnsZoneId);

      if (zone == null) {
        throw new CloudException("No such zone: " + providerDnsZoneId);
      }
      if (recordType.equals(DNSRecordType.A)
          || recordType.equals(DNSRecordType.AAAA)
          || recordType.equals(DNSRecordType.CNAME)
          || recordType.equals(DNSRecordType.MX)) {
        if (name.endsWith(zone.getDomainName() + ".")) {
          name = name.substring(0, name.length() - 1);
        } else if (!name.endsWith(zone.getDomainName())) {
          name = name + "." + zone.getDomainName();
        }
      }
      ProviderContext ctx = provider.getContext();

      if (ctx == null) {
        logger.error("No context exists for this request");
        throw new InternalException("No context exists for this request");
      }
      DNSRecord lastRecord = null;

      for (String value : values) {
        if (value != null) {
          NovaMethod method = new NovaMethod(provider);

          HashMap<String, Object> wrapper = new HashMap<String, Object>();
          ArrayList<Map<String, Object>> records = new ArrayList<Map<String, Object>>();

          HashMap<String, Object> record = new HashMap<String, Object>();

          record.put("name", name);
          record.put("data", value);
          record.put("type", recordType.name());
          record.put("ttl", ttl > 0 ? ttl : 3600);

          records.add(record);

          wrapper.put("records", records);

          JSONObject response =
              method.postString(
                  SERVICE,
                  RESOURCE,
                  providerDnsZoneId + "/records",
                  new JSONObject(wrapper),
                  false);

          try {
            if (response != null && response.has("jobId")) {
              response = waitForJob(response.getString("jobId"));
              if (response != null && response.has("records")) {
                JSONArray list = response.getJSONArray("records");

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

                  if (r != null) {
                    lastRecord = r;
                  }
                }
              }
            }
          } catch (JSONException e) {
            logger.error("createDnsZone(): JSON error parsing response: " + e.getMessage());
            e.printStackTrace();
            throw new CloudException(
                CloudErrorType.COMMUNICATION,
                200,
                "invalidResponse",
                "JSON error parsing " + response);
          }
        }
      }
      if (lastRecord == null) {
        logger.error("addDnsRecord(): No record was created, but no error specified");
        throw new CloudException("No record was created, but no error specified");
      }
      return lastRecord;
    } finally {
      APITrace.end();
    }
  }