/** async get response from xdm client */
  public void getResponse(XcapUriKey key, int responseCode, String mimetype, String content) {

    DocumentSelector documentSelector = null;
    if (key instanceof DocumentUriKey) {
      documentSelector = ((DocumentUriKey) key).getDocumentSelector();
    } else if (key instanceof AttributeUriKey) {
      documentSelector = ((AttributeUriKey) key).getDocumentSelector();
    } else if (key instanceof ElementUriKey) {
      documentSelector = ((ElementUriKey) key).getDocumentSelector();
    } else {
      try {
        documentSelector =
            Parser.parseDocumentSelector(key.getResourceSelector().getDocumentSelector());
      } catch (ParseException e) {
        // won't happen
        logger.error("bug, a xcap uri key document selector string could not be parsed", e);
      }
    }

    if (responseCode == 200) {
      // just simulate a document update
      documentUpdated(documentSelector, null, null, content);
    } else {
      // let's be friendly with clients without xcap, allow subscription
      String notifierWithoutParams = getUser(documentSelector);
      if (logger.isInfoEnabled()) {
        logger.info(notifierWithoutParams + " pres-rules not found, allowing subscription");
      }
      Map combinedRules = sbb.getCombinedRules();
      if (combinedRules != null) {
        for (Object object : combinedRules.keySet()) {
          PresRuleCMPKey cmpKey = (PresRuleCMPKey) object;
          if (cmpKey.getNotifierWithoutParams().equals(notifierWithoutParams)) {
            OMAPresRule combinedRule = (OMAPresRule) combinedRules.get(cmpKey);
            combinedRule.setProvideAllDevices(true);
            combinedRule.setProvideAllAttributes(true);
            combinedRule.setProvideAllPersons(true);
            combinedRule.setProvideAllServices(true);
            combinedRule.setSubHandling(SubHandlingAction.allow);
            // notify auth changed
            sbb.getParentSbbCMP()
                .authorizationChanged(
                    cmpKey.getSubscriber(),
                    cmpKey.getNotifier(),
                    "presence",
                    cmpKey.getEventId(),
                    combinedRule.getSubHandling().getResponseCode());
          }
        }
        sbb.setCombinedRules(combinedRules);
      }
    }

    // subscribe to changes in this pres-rules doc
    sbb.getXDMClientControlSbb().subscribeDocument(documentSelector);
  }
  public void documentUpdated(
      DocumentSelector documentSelector, String oldETag, String newETag, String documentAsString) {

    if (!documentSelector.getAUID().equals("org.openmobilealliance.pres-rules")
        && !documentSelector.getAUID().equals("pres-rules")) {
      // not a pres-rules doc, maybe it's coming here because of
      // integrated servers using xdm client
      return;
    }

    String notifierWithoutParams = getUser(documentSelector);

    // unmarshall doc
    Ruleset ruleset = unmarshallRuleset(documentAsString);
    if (ruleset == null) {
      logger.error(
          "rcvd ruleset update from xdm client but unmarshalling of ruleset failed, ignoring update");
      return;
    }

    // get current combined rules from cmp
    Map combinedRules = sbb.getCombinedRules();
    if (combinedRules == null) {
      combinedRules = new HashMap();
    }
    // for each combined rules that has the user that updated the doc as
    // notifier reprocess the rules
    for (Object key : combinedRules.keySet()) {
      PresRuleCMPKey cmpKey = (PresRuleCMPKey) key;
      if (cmpKey.getNotifierWithoutParams().equals(notifierWithoutParams)) {
        OMAPresRule oldCombinedRule = (OMAPresRule) combinedRules.get(cmpKey);
        RulesetProcessor rulesetProcessor =
            new RulesetProcessor(cmpKey.getSubscriber(), notifierWithoutParams, ruleset, sbb);
        OMAPresRule newCombinedRule = rulesetProcessor.getCombinedRule();
        combinedRules.put(cmpKey, newCombinedRule);
        // check permission changed
        if (oldCombinedRule.getSubHandling().getResponseCode()
            != newCombinedRule.getSubHandling().getResponseCode()) {
          sbb.getParentSbbCMP()
              .authorizationChanged(
                  cmpKey.getSubscriber(),
                  cmpKey.getNotifier(),
                  "presence",
                  cmpKey.getEventId(),
                  newCombinedRule.getSubHandling().getResponseCode());
        }
      }
    }

    sbb.setCombinedRules(combinedRules);
  }