sclass StructureStringIndenter {
  // how many levels to indent, max
  settable int levels = 100;
  
  // inline lowest levels of char count is not higher than this
  settable int inlineChars = 40;
  
  settable bool verbose;
  
  // internal
  LS tok;
  Map<Int> bracketMap;
  
  S get(S s) {
    if (s == null) null;
    tok = javaTokForStructure(s);
    int n = l(tok);
    bracketMap = getBracketMap(tok, l1 isOpeningBracket, l1 isClosingBracket);
    
    // being careful because this.levels might be Int.MAX_VALUE
    int levels = clampToInt(this.levels*2L);
    
    new StringBuilder buf;
    int indent = 0;
    for i to n: {
      S t = tok.get(i);
      if (isOpeningBracket(t)) {
        S prev = get(tok, i-2);
        
        Int j = or(bracketMap.get(i), n);
        if (j != null &&
          (eq(prev, "intarray")
          || !tokenRangeLongerThanNChars(tok, i+1, j+1, inlineChars))) {
          // ONE LINE
          
          buf.append(joinSubList(tok, i, j+1));
          i = j;
        } else {
          // MULTIPLE LINES
          
          if (verbose)
            print("Bracket part longer than " + inlineChars + " chars: " + quote(shortenJoinSubList(inlineChars, tok, i, j+1)));
          indent += 2;
          buf.append(t);
          if (indent <= levels)
            buf.append("\n").append(spaces(indent));
        }
      } else if (isClosingBracket(t)) {
        indent -= 2;
        if (indent < levels)
          buf.append("\n").append(spaces(indent));
        buf.append(t);
      } else if (indent <= levels && eq(t, ",")) {
        buf.append(t).append("\n").append(spaces(indent));
        i++;
      } else
        buf.append(t);
    }
    
    ret str(buf);
  }
}