/**
   * Add an new empty feed::dasextension element with only a completed management element to the
   * given Feed. Sets the responseTime value to now. Note: A proper sites::site element must be
   * added to the new feed::dasextension element for this new feed::dasextension element to be
   * valid.
   *
   * @param feed - mandatory
   * @return
   */
  private Feed addEmptyDasExtension(Feed feed) {

    // check to make sure there's a dasextension
    QName dasextensionQname = new QName(this.dasextensionNamespace, "dasextension");
    ExtensibleElement dasExt = feed.getExtension(dasextensionQname);
    if (NullChecker.isEmpty(dasExt)) {

      dasExt = feed.addExtension(dasextensionQname);

      // add the dasextension::management element
      QName managementQname = new QName(this.dasextensionNamespace, "management");
      ExtensibleElement management = dasExt.getExtension(managementQname);
      if (NullChecker.isEmpty(management)) {
        management = dasExt.addExtension(managementQname);
      }

      QName responseTimeQname = new QName(this.dasextensionNamespace, "responseTime");
      ExtensibleElement responseTime = management.getExtension(responseTimeQname);
      if (NullChecker.isEmpty(responseTime)) {
        responseTime = management.addExtension(responseTimeQname);
      }

      // set/reset the response time to now
      XMLGregorianCalendar xmlGregCalResponseTime =
          GregorianDateUtil.getGregorianCalendarByDate(new Date());
      responseTime.setText(xmlGregCalResponseTime.toString()); // TODO: Verify date format
    }
    return feed;
  }
  /**
   * Adds a single error element into the DAS dasextension Atom Feed, i.e. adds one of the following
   * inside of feed::dasextension::query::errors: <error> <errorSeverity></errorSeverity>
   * <errorCode></errorCode> <errorValue></errorValue> <errorLocation></errorLocation> </error>
   * Note: The feed parameter must contain a constructed DAS dasextension Atom Feed.
   *
   * @param feed - mandatory - must contain a valid feed::dasextension Element
   * @param errorSeverity - optional
   * @param errorCode - optional
   * @param errorValue - optional
   * @param errorLocation - optional
   * @return
   */
  public Feed addError(
      Feed feed,
      final String errorSeverity,
      final String errorCode,
      final String errorValue,
      final String errorLocation) {
    if (NullChecker.isNotEmpty(feed)) {
      // get reference to the dasextension element in feed
      ExtensibleElement dasExt =
          feed.getExtension(new QName(this.dasextensionNamespace, "dasextension"));
      if (NullChecker.isNotEmpty(dasExt)) {
        // get reference to the dasextension::query::errors element in feed
        // -- if errors doesn't exist, this method will add it
        ExtensibleElement errors = this.getErrors(dasExt);

        // add the dasextension::query::errors::error element
        QName errorQname = new QName(this.dasextensionNamespace, "error");
        ExtensibleElement errorsError = errors.addExtension(errorQname);
        if (NullChecker.isNotEmpty(errorSeverity)) {
          QName errorSeverityQname = new QName(this.dasextensionNamespace, "errorSeverity");
          ExtensibleElement errorSeverityElement = errorsError.addExtension(errorSeverityQname);
          errorSeverityElement.setText(errorSeverity);
        }
        if (NullChecker.isNotEmpty(errorCode)) {
          QName errorCodeQname = new QName(this.dasextensionNamespace, "errorCode");
          ExtensibleElement errorCodeElement = errorsError.addExtension(errorCodeQname);
          errorCodeElement.setText(errorCode);
        }
        if (NullChecker.isNotEmpty(errorValue)) {
          QName errorValueQname = new QName(this.dasextensionNamespace, "errorValue");
          ExtensibleElement errorValueElement = errorsError.addExtension(errorValueQname);
          errorValueElement.setText(errorValue);
        }
        if (NullChecker.isNotEmpty(errorLocation)) {
          QName errorLocationQname = new QName(this.dasextensionNamespace, "errorLocation");
          ExtensibleElement errorLocationElement = errorsError.addExtension(errorLocationQname);
          errorLocationElement.setText(errorLocation);
        }
      }
    }
    return feed;
  }
  /**
   * Places the org.osehra.integration.http.uri.UriInfo uriInfo instance's query parameter values
   * into the DAS dasextension Atom Feed at feed::dasextension::query::parameters. Notes: The feed
   * parameter must contain a constructed DAS dasextension Atom Feed. This method will remove any
   * existing feed::dasextension::query::parameters::entry elements before adding the new entries
   * from uriInfo.
   *
   * @param feed -mandatory - must contain a valid feed::dasextension Element
   * @param uriInfo - mandatory
   * @return
   */
  public Feed addQueryParameters(Feed feed, final javax.ws.rs.core.UriInfo uriInfo) {
    if (NullChecker.isNotEmpty(feed)) {
      // get reference to the dasextension element in feed
      ExtensibleElement dasExt =
          feed.getExtension(new QName(this.dasextensionNamespace, "dasextension"));
      if (NullChecker.isNotEmpty(dasExt)) {
        // check for a UriInfo to input
        if (NullChecker.isNotEmpty(uriInfo) && !(uriInfo.getQueryParameters().isEmpty())) {
          // get or create reference to the dasextension::query::parameters element in feed
          ExtensibleElement parameters = this.getQueryParameters(dasExt);

          // discard any existing path dasextension::path::parameter::entry elements
          List<Element> queryParameterEntries = parameters.getElements();
          if (NullChecker.isNotEmpty(queryParameterEntries)) {
            for (Element curQueryParameterEntry : queryParameterEntries) {
              curQueryParameterEntry.discard();
            }
          }

          // add the dasextension::query::parameters::entry elements from uriInfo
          QName entryQname = new QName(this.dasextensionNamespace, "entry");
          QName keyQname = new QName(this.dasextensionNamespace, "key");
          QName valueQname = new QName(this.dasextensionNamespace, "value");

          MultivaluedMap<String, String> queryParametersExt = uriInfo.getQueryParameters();
          Set<Map.Entry<String, List<String>>> queryParamsEntries = queryParametersExt.entrySet();
          for (Map.Entry<String, List<String>> queryParameterEntry : queryParamsEntries) {
            ExtensibleElement entry = parameters.addExtension(entryQname);
            ExtensibleElement key = entry.addExtension(keyQname);
            key.setText(queryParameterEntry.getKey());
            for (String entryValue : queryParameterEntry.getValue()) {
              ExtensibleElement value = entry.addExtension(valueQname);
              value.setText(entryValue);
            }
          }
        }
      }
    }
    return feed;
  }
  /**
   * Adds a single site element into the DAS dasextension Atom Feed. i.e. adds one of the following
   * inside of feed::dasextension::query::sites: <site> <id></id> <name></name>
   * <expectedCount></expectedCount> <retrievedCount></retrievedCount> <status></status>
   * <error></error> </site> Notes: The feed parameter must contain a constructed DAS dasextension
   * Atom Feed. An existing site element with the same site::name value as the given siteName value
   * will be removed before the new site element is added.
   *
   * @param feed - mandatory - must contain a valid feed::dasextension Element
   * @param siteName - mandatory
   * @param siteId - optional
   * @param siteHttpStatus - mandatory
   * @param expectedCount - optional
   * @param retrievedCount - optional
   * @param siteErrorMessage - optional
   * @return
   */
  public Feed addSite(
      Feed feed,
      final String siteName,
      final String siteId,
      final int siteHttpStatus,
      final String expectedCount,
      final String retrievedCount,
      final String siteErrorMessage) {
    if (NullChecker.isNotEmpty(feed)) {
      // get reference to the dasextension element in feed
      ExtensibleElement dasExt =
          feed.getExtension(new QName(this.dasextensionNamespace, "dasextension"));
      if (NullChecker.isNotEmpty(dasExt)) {
        // get reference to the dasextension::query::sites element in feed
        ExtensibleElement sites = this.getSites(dasExt);

        // search for any existing site children by site::name value with
        // the new siteName, and if one is found, remove it
        List<Element> siteElements = sites.getElements();
        for (Element curSiteElement : siteElements) {
          List<Element> siteChildElements = curSiteElement.getElements();
          for (Element curSiteChildElement : siteChildElements) {
            if ("name".equals(curSiteChildElement.getQName().getLocalPart())) {
              if (siteName.equals(curSiteChildElement.getText())) {
                curSiteElement.discard();
              }
            }
          }
        }

        // add the dasextension::query::sites::site element
        QName siteQname = new QName(this.dasextensionNamespace, "site");
        ExtensibleElement site = sites.addExtension(siteQname);
        if (NullChecker.isNotEmpty(siteId)) {
          QName idQname = new QName(this.dasextensionNamespace, "id");
          ExtensibleElement idElement = site.addExtension(idQname);
          idElement.setText(siteId);
        }
        QName nameQname = new QName(this.dasextensionNamespace, "name");
        ExtensibleElement nameElement = site.addExtension(nameQname);
        nameElement.setText(siteName);
        if (NullChecker.isNotEmpty(expectedCount)) {
          QName expectedCountQname = new QName(this.dasextensionNamespace, "expectedCount");
          ExtensibleElement expectedCountElement = site.addExtension(expectedCountQname);
          expectedCountElement.setText(expectedCount);
        }
        if (NullChecker.isNotEmpty(retrievedCount)) {
          QName retrievedCountQname = new QName(this.dasextensionNamespace, "retrievedCount");
          ExtensibleElement retrievedCountElement = site.addExtension(retrievedCountQname);
          retrievedCountElement.setText(retrievedCount);
        }
        QName statusQname = new QName(this.dasextensionNamespace, "status");
        ExtensibleElement statusElement = site.addExtension(statusQname);
        String siteStatus = new Integer(siteHttpStatus).toString();
        statusElement.setText(siteStatus);
        if (NullChecker.isNotEmpty(siteErrorMessage)) {
          QName errorQname = new QName(this.dasextensionNamespace, "error");
          ExtensibleElement siteErrorElement = site.addExtension(errorQname);
          siteErrorElement.setText(siteErrorMessage);
        }
      }
    }
    return feed;
  }