private int parseBracketedNote(String s, int index, NoteContext context) {
    int indexOfEndBracket = s.indexOf(']', index);
    String stringInBrackets = s.substring(index + 1, indexOfEndBracket);
    context.noteValueAsString = stringInBrackets;
    context.isNumericNote = true;

    logger.info(
        "This note is a note represented by the dictionary value " + context.noteValueAsString);
    return indexOfEndBracket + 1;
  }
  /**
   * Returns the index with which to start parsing the next part of the string, once this method is
   * done with its part
   */
  private int parseNumericNote(String s, int index, NoteContext context) {
    int numCharsInNumber = 0;
    while (numCharsInNumber < s.length()
        && (s.charAt(index + numCharsInNumber) >= '0')
        && (s.charAt(index + numCharsInNumber) <= '9')) {
      numCharsInNumber++;
    }
    String numericNoteString = s.substring(index, index + numCharsInNumber);
    context.noteNumber = Byte.parseByte(numericNoteString);
    context.isNumericNote = true;

    logger.info("This note is a numeric note with value " + context.noteNumber);
    return index + numCharsInNumber;
  }
  /**
   * Returns the index with which to start parsing the next part of the string, once this method is
   * done with its part
   */
  private int parseLetterNote(String s, int index, NoteContext context) {
    context.isNumericNote = false;
    int originalIndex = index;
    switch (s.charAt(index)) {
      case 'C':
        context.noteNumber = 0;
        break;
      case 'D':
        context.noteNumber = 2;
        break;
      case 'E':
        context.noteNumber = 4;
        break;
      case 'F':
        context.noteNumber = 5;
        break;
      case 'G':
        context.noteNumber = 7;
        break;
      case 'A':
        context.noteNumber = 9;
        break;
      case 'B':
        context.noteNumber = 11;
        break;
      default:
        break;
    }
    index++;

    // Check for #, b, or n (sharp, flat, or natural) modifier
    boolean checkForModifiers = true;
    while (checkForModifiers) {
      if (index < s.length()) {
        switch (s.charAt(index)) {
          case '#':
            index++;
            context.noteNumber++;
            if (context.noteNumber == 12) {
              context.noteNumber = 0;
              context.octaveBias++;
            }
            break;
          case 'B':
            index++;
            context.noteNumber--;
            if (context.noteNumber == -1) {
              context.noteNumber = 11;
              context.octaveBias--;
            }
            break;
          case 'N':
            index++;
            context.isNatural = true;
            checkForModifiers = false;
            break;
          default:
            checkForModifiers = false;
            break;
        }
      } else {
        checkForModifiers = false;
      }
    }

    context.originalString = s.substring(originalIndex, index);

    logger.info(
        "Note number within an octave (C=0, B=11): "
            + context.noteNumber
            + " (with octaveBias = "
            + context.octaveBias
            + ")");
    return index;
  }