/**
   * Normalize the path by suppressing sequences like "path/.." and inner simple dots.
   *
   * <p>The result is convenient for path comparison. For other uses, notice that Windows separators
   * ("\") are replaced by simple slashes.
   *
   * @param path the original path
   * @return the normalized path
   */
  public static String normalize(String path) {
    if (path == null) {
      return Strings.EMPTY;
    }
    String pathToUse = Strings.replace(path, WINDOWS_SEPARATOR, UNIX_SEPARATOR);

    // Strip prefix from path to analyze, to not treat it as part of the
    // first path element. This is necessary to correctly parse paths like
    // "file:core/../core/io/Resource.class", where the ".." should just
    // strip the first "core" directory while keeping the "file:" prefix.
    int prefixIndex = pathToUse.indexOf(":");
    String prefix = "";
    if (prefixIndex != -1) {
      prefix = pathToUse.substring(0, prefixIndex + 1);
      pathToUse = pathToUse.substring(prefixIndex + 1);
    }
    if (pathToUse.startsWith(UNIX_SEPARATOR_STR)) {
      prefix = prefix + UNIX_SEPARATOR;
      pathToUse = pathToUse.substring(1);
    }

    String[] pathArray = Strings.split(pathToUse, UNIX_SEPARATOR_STR, false, false);
    List<String> pathElements = new LinkedList<String>();
    int tops = 0;

    for (int i = pathArray.length - 1; i >= 0; i--) {
      String element = pathArray[i];
      if (CURRENT_PATH.equals(element)) {
        // Points to current directory - drop it.
      } else if (PARENT_PATH.equals(element)) {
        // Registering top path found.
        tops++;
      } else {
        if (tops > 0) {
          // Merging path element with element corresponding to top path.
          tops--;
        } else {
          // Normal path element found.
          pathElements.add(0, element);
        }
      }
    }

    // Remaining top paths need to be retained.
    for (int i = 0; i < tops; i++) {
      pathElements.add(0, PARENT_PATH);
    }

    return prefix + Strings.join(pathElements, UNIX_SEPARATOR_STR);
  }
  public static ReflectEnum get(Class<?> enumType) {
    Assert.notNull(enumType, "enumType must not be null");
    Assert.isValidState(
        enumType.isEnum(), Strings.format("{0} is not an enum type", enumType.getName()));

    ReflectEnum reflectEnum = cache.get(enumType);

    if (null == reflectEnum) {
      reflectEnum = new ReflectEnum(enumType);
      cache.put(enumType, reflectEnum);
    }

    return reflectEnum;
  }