public static String getPathEllipsis(
      final String filename, final int maxlen, final String ellipsis) {
    final int len = filename.length();
    final int ellLen = ellipsis.length();
    Preconditions.checkArgument(maxlen >= (4 * ellLen), "Maximum length too short");

    if (len <= maxlen) {
      return filename;
    }

    // Heuristic to detect path separator used
    int i = 0;
    char sep = File.separatorChar;
    boolean found = false;
    while (!found && (i < len)) {
      sep = filename.charAt(i);
      found = ((sep == '/') || (sep == '\\'));
      i++;
    }

    final StringBuilder result = new StringBuilder();
    if (!found) {
      // Filename only, just truncate and add ellipsis
      result.append(filename.substring(0, maxlen - ellLen));
      result.append(ellipsis);
    } else {
      // Since filenames contain valuable information, split the string
      // right before the filename and truncate both halves.
      final int lastComp = filename.lastIndexOf(sep);

      final int splitLen = maxlen - (len - lastComp);
      final int splitPos = (splitLen / 2) - (ellLen / 2);
      if (splitPos > 0) {
        // Left half
        result.append(filename.substring(0, (splitPos - (ellLen % 2)) + (splitLen % 2)));
        // Ellipsis
        result.append(ellipsis);
        // Right half and filename
        result.append(filename.substring((lastComp - splitPos) + (ellLen % 2)));
      } else {
        // The split point is negative, this means the filename is too
        // long. Handle this specially by keeping the first 3
        // characters, add an ellipsis and truncate the rest. This is
        // done because the first few characters can convey useful
        // information (on Windows, for example, the drive letter).
        result.append(filename.substring(0, 3));
        result.append(ellipsis);
        result.append(filename.substring(lastComp, (lastComp + maxlen) - 3 - (2 * ellLen)));
        result.append(ellipsis);
      }
    }

    return result.toString();
  }
Shortens a filename to a specified length by adding path ellipsis. Applies a heuristic to work
for both Windows and Unix style paths.

@param filename the filename to shorten
@param maxlen the maximum number of characters to return
@param ellipsis the string to be used as an ellipsis
@return the truncated string with ellipsis added
java/zylib/src/main/java/com/google/security/zynamics/zylib/io/FileUtils.java