code: @SuppressWarnings("unchecked")
    private Map<String, Object> readMap(char openBrace, char closeBrace, char keyValueSeparator) {
      if (readChar() != openBrace) throw new AssertionError();
      Map<String, Object> result = new LinkedHashMap<>();
      while (true) {
        if (peekChar() == closeBrace) {
          // If we see the close brace, finish immediately. This handles {}/[] and ,}/,] cases.
          pos++;
          return result;
        }
  
        OptionElement option = readOption(keyValueSeparator);
        String name = option.name();
        Object value = option.value();
        if (value instanceof OptionElement) {
          @SuppressWarnings("unchecked")
          Map<String, Object> nested = (Map<String, Object>) result.get(name);
          if (nested == null) {
            nested = new LinkedHashMap<>();
            result.put(name, nested);
          }
          OptionElement valueOption = (OptionElement) value;
          nested.put(valueOption.name(), valueOption.value());
        } else {
          // Add the value(s) to any previous values with the same key
          Object previous = result.get(name);
          if (previous == null) {
            result.put(name, value);
          } else if (previous instanceof List) {
            // Add to previous List
            addToList((List<Object>) previous, value);
          } else {
            List<Object> newList = new ArrayList<>();
            newList.add(previous);
            addToList(newList, value);
            result.put(name, newList);
          }
        }
  
        // ',' separator is optional, skip if present
        if (peekChar() == ',') {
          pos++;
        }
      }
    }
docs: Returns a map of string keys and values. This is similar to a JSON object,
  with '{' and '}' surrounding the map, ':' separating keys from values, and
  ',' separating entries.