@Override
  public void parseResponse(
      ChallengeResponse challenge, Request request, Series<Header> httpHeaders) {
    if (challenge.getRawValue() != null) {
      HeaderReader<Object> hr = new HeaderReader<Object>(challenge.getRawValue());

      try {
        Parameter param = hr.readParameter();

        while (param != null) {
          try {
            if ("username".equals(param.getName())) {
              challenge.setIdentifier(param.getValue());
            } else if ("realm".equals(param.getName())) {
              challenge.setRealm(param.getValue());
            } else if ("nonce".equals(param.getName())) {
              challenge.setServerNonce(param.getValue());
            } else if ("uri".equals(param.getName())) {
              challenge.setDigestRef(new Reference(param.getValue()));
            } else if ("response".equals(param.getName())) {
              challenge.setSecret(param.getValue());
            } else if ("algorithm".equals(param.getName())) {
              challenge.setDigestAlgorithm(param.getValue());
            } else if ("cnonce".equals(param.getName())) {
              challenge.setClientNonce(param.getValue());
            } else if ("opaque".equals(param.getName())) {
              challenge.setOpaque(param.getValue());
            } else if ("qop".equals(param.getName())) {
              challenge.setQuality(param.getValue());
            } else if ("nc".equals(param.getName())) {
              challenge.setServerNounceCount(Integer.valueOf(param.getValue(), 16));
            } else {
              challenge.getParameters().add(param);
            }
          } catch (Throwable e) {
            Context.getCurrentLogger()
                .log(Level.WARNING, "Unable to parse the challenge request header parameter", e);
          }
          if (hr.skipValueSeparator()) {
            param = hr.readParameter();
          } else {
            param = null;
          }
        }
      } catch (Exception e) {
        Context.getCurrentLogger()
            .log(Level.WARNING, "Unable to parse the challenge request header parameter", e);
      }
    }
  }
  @Override
  public void parseRequest(
      ChallengeRequest challenge, Response response, Series<Header> httpHeaders) {
    if (challenge.getRawValue() != null) {
      HeaderReader<Object> hr = new HeaderReader<Object>(challenge.getRawValue());

      try {
        Parameter param = hr.readParameter();

        while (param != null) {
          try {
            if ("realm".equals(param.getName())) {
              challenge.setRealm(param.getValue());
            } else if ("domain".equals(param.getName())) {
              challenge.getDomainRefs().add(new Reference(param.getValue()));
            } else if ("nonce".equals(param.getName())) {
              challenge.setServerNonce(param.getValue());
            } else if ("opaque".equals(param.getName())) {
              challenge.setOpaque(param.getValue());
            } else if ("stale".equals(param.getName())) {
              challenge.setStale(Boolean.valueOf(param.getValue()));
            } else if ("algorithm".equals(param.getName())) {
              challenge.setDigestAlgorithm(param.getValue());
            } else if ("qop".equals(param.getName())) {
              // challenge.setDigestAlgorithm(param.getValue());
            } else {
              challenge.getParameters().add(param);
            }

            if (hr.skipValueSeparator()) {
              param = hr.readParameter();
            } else {
              param = null;
            }
          } catch (Exception e) {
            Context.getCurrentLogger()
                .log(Level.WARNING, "Unable to parse the challenge request header parameter", e);
          }
        }
      } catch (Exception e) {
        Context.getCurrentLogger()
            .log(Level.WARNING, "Unable to parse the challenge request header parameter", e);
      }
    }
  }
  /**
   * Returns the condition data applying to this call.
   *
   * @return The condition data applying to this call.
   */
  @Override
  public Conditions getConditions() {
    Conditions result = super.getConditions();

    if (!this.conditionAdded) {
      if (getHeaders() != null) {
        // Extract the header values
        String ifMatchHeader = getHeaders().getValues(HeaderConstants.HEADER_IF_MATCH);
        String ifNoneMatchHeader = getHeaders().getValues(HeaderConstants.HEADER_IF_NONE_MATCH);
        Date ifModifiedSince = null;
        Date ifUnmodifiedSince = null;
        String ifRangeHeader = getHeaders().getFirstValue(HeaderConstants.HEADER_IF_RANGE, true);

        for (Header header : getHeaders()) {
          if (header.getName().equalsIgnoreCase(HeaderConstants.HEADER_IF_MODIFIED_SINCE)) {
            ifModifiedSince = HeaderReader.readDate(header.getValue(), false);
          } else if (header
              .getName()
              .equalsIgnoreCase(HeaderConstants.HEADER_IF_UNMODIFIED_SINCE)) {
            ifUnmodifiedSince = HeaderReader.readDate(header.getValue(), false);
          }
        }

        // Set the If-Modified-Since date
        if ((ifModifiedSince != null) && (ifModifiedSince.getTime() != -1)) {
          result.setModifiedSince(ifModifiedSince);
        }

        // Set the If-Unmodified-Since date
        if ((ifUnmodifiedSince != null) && (ifUnmodifiedSince.getTime() != -1)) {
          result.setUnmodifiedSince(ifUnmodifiedSince);
        }

        // Set the If-Match tags
        List<Tag> match = null;
        Tag current = null;
        if (ifMatchHeader != null) {
          try {
            HeaderReader<Object> hr = new HeaderReader<Object>(ifMatchHeader);
            String value = hr.readRawValue();

            while (value != null) {
              current = Tag.parse(value);

              // Is it the first tag?
              if (match == null) {
                match = new ArrayList<Tag>();
                result.setMatch(match);
              }

              // Add the new tag
              match.add(current);

              // Read the next token
              value = hr.readRawValue();
            }
          } catch (Exception e) {
            this.context
                .getLogger()
                .log(Level.INFO, "Unable to process the if-match header: " + ifMatchHeader);
          }
        }

        // Set the If-None-Match tags
        List<Tag> noneMatch = null;
        if (ifNoneMatchHeader != null) {
          try {
            HeaderReader<Object> hr = new HeaderReader<Object>(ifNoneMatchHeader);
            String value = hr.readRawValue();

            while (value != null) {
              current = Tag.parse(value);

              // Is it the first tag?
              if (noneMatch == null) {
                noneMatch = new ArrayList<Tag>();
                result.setNoneMatch(noneMatch);
              }

              noneMatch.add(current);

              // Read the next token
              value = hr.readRawValue();
            }
          } catch (Exception e) {
            this.context
                .getLogger()
                .log(
                    Level.INFO, "Unable to process the if-none-match header: " + ifNoneMatchHeader);
          }
        }

        if (ifRangeHeader != null && ifRangeHeader.length() > 0) {
          Tag tag = Tag.parse(ifRangeHeader);
          if (tag != null) {
            result.setRangeTag(tag);
          } else {
            Date date = HeaderReader.readDate(ifRangeHeader, false);
            result.setRangeDate(date);
          }
        }
      }

      this.conditionAdded = true;
    }

    return result;
  }