/**
   * Updates a registration
   *
   * @param registration The registration to update
   * @return The updated registration
   * @throws Exception
   */
  private Registration upsertRegistrationInternal(Registration registration) throws Exception {
    Connection conn = new Connection(mConnectionString);

    String resource = registration.getURI();
    String content = registration.toXml();

    String response = conn.executeRequest(resource, content, XML_CONTENT_TYPE, "PUT");

    Registration result;
    if (PnsSpecificRegistrationFactory.getInstance().isTemplateRegistration(response)) {
      result =
          PnsSpecificRegistrationFactory.getInstance()
              .createTemplateRegistration(mNotificationHubPath);
    } else {
      result =
          PnsSpecificRegistrationFactory.getInstance()
              .createNativeRegistration(mNotificationHubPath);
    }

    result.loadXml(response, mNotificationHubPath);

    storeRegistrationId(result.getName(), result.getRegistrationId(), registration.getPNSHandle());

    return result;
  }
  /**
   * Deletes a registration and removes it from local storage
   *
   * @param regInfo The reginfo JSON object
   * @throws Exception
   */
  private void deleteRegistrationInternal(String registrationName, String registrationId)
      throws Exception {
    Connection conn = new Connection(mConnectionString);
    String resource = mNotificationHubPath + "/Registrations/" + registrationId;

    try {
      conn.executeRequest(
          resource, null, XML_CONTENT_TYPE, "DELETE", new BasicHeader("If-Match", "*"));
    } finally {
      removeRegistrationId(registrationName);
    }
  }
  private String createRegistrationId() throws Exception {
    Connection conn = new Connection(mConnectionString);

    String resource = mNotificationHubPath + "/registrationids/";
    String response =
        conn.executeRequest(
            resource, null, XML_CONTENT_TYPE, "POST", NEW_REGISTRATION_LOCATION_HEADER);

    URI regIdUri = new URI(response);
    String[] pathFragments = regIdUri.getPath().split("/");
    String result = pathFragments[pathFragments.length - 1];

    return result;
  }
  private void refreshRegistrationInformation(String pnsHandle) throws Exception {
    if (isNullOrWhiteSpace(pnsHandle)) {
      throw new IllegalArgumentException("pnsHandle");
    }

    // delete old registration information
    Editor editor = mSharedPreferences.edit();
    Set<String> keys = mSharedPreferences.getAll().keySet();
    for (String key : keys) {
      if (key.startsWith(STORAGE_PREFIX + REGISTRATION_NAME_STORAGE_KEY)) {
        editor.remove(key);
      }
    }

    editor.commit();

    // get existing registrations
    Connection conn = new Connection(mConnectionString);

    String filter =
        PnsSpecificRegistrationFactory.getInstance().getPNSHandleFieldName()
            + " eq '"
            + pnsHandle
            + "'";

    String resource =
        mNotificationHubPath + "/Registrations/?$filter=" + URLEncoder.encode(filter, "UTF-8");
    String content = null;
    String response = conn.executeRequest(resource, content, XML_CONTENT_TYPE, "GET");

    DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
    builder.setEntityResolver(
        new EntityResolver() {
          @Override
          public InputSource resolveEntity(String publicId, String systemId)
              throws SAXException, IOException {
            return null;
          }
        });

    Document doc = builder.parse(new InputSource(new StringReader(response)));

    doc.getDocumentElement().normalize();
    Element root = doc.getDocumentElement();

    // for each registration, parse it
    NodeList entries = root.getElementsByTagName("entry");
    for (int i = 0; i < entries.getLength(); i++) {
      Registration registration;
      Element entry = (Element) entries.item(i);
      String xml = getXmlString(entry);
      if (PnsSpecificRegistrationFactory.getInstance().isTemplateRegistration(xml)) {
        registration =
            PnsSpecificRegistrationFactory.getInstance()
                .createTemplateRegistration(mNotificationHubPath);
      } else {
        registration =
            PnsSpecificRegistrationFactory.getInstance()
                .createNativeRegistration(mNotificationHubPath);
      }

      registration.loadXml(xml, mNotificationHubPath);

      storeRegistrationId(
          registration.getName(), registration.getRegistrationId(), registration.getPNSHandle());
    }

    mIsRefreshNeeded = false;
  }