/** Save all engine elements that current in Cache to underlying data store */
  public void save() throws DataAdapterException {
    File policyFile = null;
    try {
      String schema = getPolicyDefaultSchema();
      // Retrieve the schema file from given path or classpath, and verify if it exists.
      schema = verifySchemaFile(schema);

      PDP currentPDP = DataStoreHelper.getPDP(this);
      CacheManager cacheMgr = CacheManager.getInstance(currentPDP);
      AbstractPolicy[] allPolicies = cacheMgr.getAllPolicies();

      for (int i = 0; i < allPolicies.length; i++) {
        AbstractPolicy policy = allPolicies[i];
        policyFile = policyFilesByID.get(policy.getId());
        // If no existing file, this means the policy is new added, we create a new file for it.
        if (policyFile == null) {
          policyFile = new File(POLICY_FILE_PREFIX + policy.getId() + POLICY_FILE_SUFFIX);
        }
        // Dump the xml element to file. Note, we don't need clean up the directory.
        dumpPolicy(policy, new FileOutputStream(policyFile));
      }
    } catch (Exception e) {
      throw new DataAdapterException(
          "Error occurs when saving policy file"
              + (policyFile == null ? "." : " : '" + policyFile.getName() + "'"),
          e);
    }
  }
  private static NodeList evaluateXPath(EvaluationContext ctx, String exp)
      throws IndeterminateException {
    try {
      AbstractPolicy evaluatingPolicy = ctx.getCurrentEvaluatingPolicy();
      if (evaluatingPolicy != null) {
        isPolicyXPathVersionSupported(evaluatingPolicy);

        NamespaceContextProvider nsCtx = new NamespaceContextProvider();
        Map<String, String> nsMap = evaluatingPolicy.getPolicyNamespaceMappings();
        Iterator<String> keys = nsMap.keySet().iterator();
        while (keys.hasNext()) {
          String key = keys.next();
          nsCtx.addNSMapping(key, nsMap.get(key));
        }
        xpath.setNamespaceContext(nsCtx);
      }

      return (NodeList) xpath.evaluate(exp, ctx.getRequest().getRootNode(), XPathConstants.NODESET);
    } catch (IndeterminateException intEx) {
      throw intEx;
    } catch (Exception ex) {
      throw new IndeterminateException("Error occurs while evaluating XPath expression : " + exp);
    }
  }