public String[] getPaths(
     ContextualisedStorage root,
     CSPRequestCredentials creds,
     CSPRequestCache cache,
     String rootPath,
     JSONObject restriction)
     throws ExistException, UnimplementedException, UnderlyingStorageException {
   String parts[] = split(rootPath, true);
   if ("".equals(parts[0])) {
     return children.keySet().toArray(new String[0]);
   } else {
     List<String> out = new ArrayList<String>();
     for (Map.Entry<String, ContextualisedStorage> e : children.entrySet()) {
       if (e.getKey().equals(parts[0])) {
         ContextualisedStorage storage = e.getValue();
         String[] paths = storage.getPaths(root, creds, cache, parts[1], restriction);
         if (paths == null) continue;
         for (String s : paths) {
           out.add(s);
         }
       }
     }
     return out.toArray(new String[0]);
   }
 }
  /**
   * For each type of storage, this function will get the paths and pagination information, this
   * will be brought together into one object
   */
  public JSONObject getPathsJSON(
      ContextualisedStorage root,
      CSPRequestCredentials creds,
      CSPRequestCache cache,
      String rootPath,
      JSONObject restriction)
      throws ExistException, UnimplementedException, UnderlyingStorageException {
    try {

      // XXX THIS SHOULD BE LOOKED AT AND CHANGED !!!
      JSONObject out = new JSONObject();
      JSONObject pagination = new JSONObject();
      JSONObject moredata = new JSONObject();
      boolean passed = false;
      List<String[]> separatelists = new ArrayList<String[]>();
      String parts[] = split(rootPath, true);
      if ("".equals(parts[0])) {
        return out.put("listItems", children.keySet().toArray(new String[0]));
      } else {
        List<String> list = new ArrayList<String>();
        for (Map.Entry<String, ContextualisedStorage> e : children.entrySet()) {
          if (e.getKey().equals(parts[0])) {
            ContextualisedStorage storage = e.getValue();
            JSONObject data = storage.getPathsJSON(root, creds, cache, parts[1], restriction);
            if (data == null) {
              data = new JSONObject();
              data.put("listItems", new String[0]);
            }
            if (data.has("moredata")) {
              moredata = data.getJSONObject("moredata");
            }
            JSONObject paging = new JSONObject();
            if (data.has("pagination")) {
              paging = data.getJSONObject("pagination");
            }
            if (!passed) {
              pagination = paging;
              passed = true;
            } else {
              pagination.put(
                  "totalItems", pagination.getInt("totalItems") + paging.getInt("totalItems"));
              int pageSize = pagination.getInt("pageSize");
              int totalinpage = pagination.getInt("itemsInPage") + paging.getInt("itemsInPage");
              if (totalinpage > pageSize) {
                pagination.put("itemsInPage", pageSize);
              } else {
                pagination.put("itemsInPage", totalinpage);
              }
            }

            // create one merged list
            String[] paths = (String[]) data.get("listItems");
            if (paths == null) {
              continue;
            }
            for (String s : paths) {
              list.add(s);
            }

            // keep the separate lists in a field
            separatelists.add(paths);
          }
        }

        pagination.put("separatelists", separatelists);
        out.put("moredata", moredata);
        out.put("pagination", pagination);
        out.put("listItems", list.toArray(new String[0]));

        return out;
      }
    } catch (JSONException e) {
      throw new UnderlyingStorageException("Error parsing JSON");
    }
  }