private int parseNewStyleSubstitution(List<FormatStringChunk> results, int end, int autoPositionedFieldsCount) {
    final NewStyleSubstitutionChunk chunk = new NewStyleSubstitutionChunk(myPos);
    chunk.setEndIndex(end);

    // skip "{"
    myPos++;
    // name
    final int nameEnd = StringUtil.indexOfAny(myLiteral, "!:.[}", myPos, end);
    if (nameEnd > 0 && myPos < nameEnd) {
      final String name = myLiteral.substring(myPos, nameEnd);
      try {
        final int number = Integer.parseInt(name);
        chunk.setManualPosition(number);
      }
      catch (NumberFormatException e) {
        chunk.setMappingKey(name);
      }
      myPos = nameEnd;
    }
    else {
      chunk.setAutoPosition(autoPositionedFieldsCount);
      autoPositionedFieldsCount++;
    }

    // parse field name attribute name
    if (isAt('.')) {
      myPos++;

      final int attributeEnd = StringUtil.indexOfAny(myLiteral, "!:.[}", myPos, end);
      if (attributeEnd > 0 && myPos < attributeEnd) {
        final String attributeName = myLiteral.substring(myPos, attributeEnd);
        chunk.setMappingKeyAttributeName(attributeName);
        myPos = attributeEnd;
      }
    }

    // parse field name element indexes
    if (isAt('[')) {
      myPos++;

      final int indexElementEnd = StringUtil.indexOfAny(myLiteral, "!:.]", myPos, end);
      if (indexElementEnd > 0 && myPos < indexElementEnd) {
        final String index = myLiteral.substring(myPos, indexElementEnd);
        chunk.setMappingKeyElementIndex(index);
        myPos = indexElementEnd + 1;
      }
    }

    // skip other attribute names and element indexes
    while (isAt('.') || isAt('[')) {
      if (isAt('.')) {
        myPos++;
        final int attributeEnd = StringUtil.indexOfAny(myLiteral, "!:.[", myPos, end);
        if (attributeEnd > 0 && myPos < attributeEnd) {
          myPos = attributeEnd;
        }
      }
      else {
        myPos++;
        final int attributeEnd = StringUtil.indexOf(myLiteral, ']', myPos, end);
        if (attributeEnd > 0 && myPos < attributeEnd) {
          myPos = attributeEnd + 1;
        }
      }
    }

    // conversion
    myPos = Math.max(myPos, StringUtil.indexOf(myLiteral, '!', myPos, end) + 1);
    final int conversionEnd = StringUtil.indexOfAny(myLiteral, ":}", myPos, end);
    if (conversionEnd - myPos == 1) {
      final String conversion = myLiteral.substring(myPos, conversionEnd);
      if (StringUtil.containsAnyChar(conversion, CONVERSIONS)) {
        chunk.setConversion(conversion);
        myPos = conversionEnd;
      }
    }

    // parse format spec
    // [[fill]align][sign][#][0][width][,][.precision][type]
    if (isAt(':')) {
      //skip ":"
      myPos++;

      //skip align options
      myPos = Math.max(myPos, StringUtil.indexOfAny(myLiteral, ALIGN_SYMBOLS, myPos, end) + 1);

      if (isAtSet(SIGN_SYMBOLS)) {
        chunk.setSignOption();
        myPos++;
      }

      if (isAt(ALTERNATE_FORM_SYMBOL)) {
        chunk.setAlternateForm();
        myPos++;
      }

      if (isAt(ZERO_PADDING_SYMBOL)) {
        chunk.setZeroPadding();
        myPos++;
      }

      chunk.setWidth(parseWhileCharacterInSet(DIGITS));

      if (isAt(',')) {
        myPos++;
        chunk.setThousandsSeparator();
      }

      if (isAt('.')) {
        myPos++;
        chunk.setPrecision(parseWhileCharacterInSet(DIGITS));
      }

      if (myPos < end - 1) {
        chunk.setConversionType(myLiteral.charAt(myPos));
      }
    }


    results.add(chunk);
    return autoPositionedFieldsCount;
  }
private int parseNewStyleSubstitution(List<FormatStringChunk> results, int end, int autoPositionedFieldsCount)