/**
   * This method compresses the list of URIs to identify common patterns.
   *
   * @param uris The URIs
   * @return The compressed list of URIs
   */
  protected static List<URIInfo> compressURIInfo(List<URIInfo> uris) {
    List<URIInfo> others = new ArrayList<URIInfo>();

    URIPart rootPart = new URIPart();

    for (int i = 0; i < uris.size(); i++) {
      URIInfo uri = uris.get(i);

      if (uri.getUri() != null && uri.getUri().length() > 0 && uri.getUri().charAt(0) == '/') {
        String[] parts = uri.getUri().split("/");

        buildTree(rootPart, parts, 1, uri.getEndpointType());

      } else {
        others.add(uri);
      }
    }

    if (others.size() == uris.size()) {
      return uris;
    }

    // Construct new list
    rootPart.collapse();

    List<URIInfo> info = extractURIInfo(rootPart);

    // Initialise the URI info
    initURIInfo(info);

    return info;
  }
  /**
   * This method initialises the list of URI information.
   *
   * @param uris The URI information
   */
  protected static void initURIInfo(List<URIInfo> uris) {
    for (int i = 0; i < uris.size(); i++) {
      URIInfo info = uris.get(i);

      info.setRegex(createRegex(info.getUri(), info.metaURI()));

      if (info.metaURI()) {
        StringBuilder template = new StringBuilder();

        String[] parts = info.getUri().split("/");

        String part = null;
        int paramNo = 1;

        for (int j = 1; j < parts.length; j++) {
          template.append("/");

          if (parts[j].equals("*")) {
            if (part == null) {
              template.append("{");
              template.append("param");
              template.append(paramNo++);
              template.append("}");
            } else {
              // Check if plural
              if (part.length() > 1 && part.charAt(part.length() - 1) == 's') {
                part = part.substring(0, part.length() - 1);
              }
              template.append("{");
              template.append(part);
              template.append("Id}");
            }
            part = null;
          } else {
            part = parts[j];
            template.append(part);
          }
        }

        info.setTemplate(template.toString());
      }
    }
  }