docs: public boolean parseString(final String pStringToParse) {
  
          if (debugging) {
              out.println("parsing \"" + pStringToParse + "\"...");
          }
  
          // Update statistics
          totalNumberOfStringsParsed++;
  
          // Check string to be parsed for nullness
          if (pStringToParse == null) {
              if (debugging) {
                  out.println("string to be parsed is null - rejection!");
              }
              return false;
          }
  
          // Create parsable string
          ParsableString parsableString = new ParsableString(pStringToParse);
  
          // Check string to be parsed
          if (!parsableString.checkString()) {
              if (debugging) {
                  out.println("one or more characters in string to be parsed are not legal characters - rejection!");
              }
              return false;
          }
  
          // Check if automaton is correctly initialized
          if (!initialized) {
              System.err.println("automaton is not initialized - rejection!");
              return false;
          }
  
          // Check if automaton is trivial (accepts all strings)
          if (isTrivialAutomaton()) {
              if (debugging) {
                  out.println("automaton represents a trivial string mask (accepts all strings) - acceptance!");
              }
              return true;
          }
  
          // Check if string to be parsed is empty
          if (parsableString.isEmpty()) {
              if (debugging) {
                  out.println("string to be parsed is empty and not trivial automaton - rejection!");
              }
              return false;
          }
  
          // Flag and more to indicate that state skipping due to sequence of '?' succeeding a '*' has been performed
          boolean hasPerformedFreeRangeMovement = false;
          int numberOfFreePassCharactersRead_SinceLastFreePassState = 0;
          int numberOfParsedCharactersRead_SinceLastFreePassState = 0;
          WildcardStringParserState runnerState = null;
  
          // Accepted by the first state?
          if ((parsableString.charArray[0] == initialState.character) || isWildcardCharacter(initialState.character)) {
              runnerState = initialState;
              parsableString.index = 0;
          }
          else {
              if (debugging) {
                  out.println("cannot enter first automaton state - rejection!");
              }
              return false;
          }
  
          // Initialize the free-pass character state visited count
          if (isFreePassCharacter(runnerState.character)) {
              numberOfFreePassCharactersRead_SinceLastFreePassState++;
          }
  
          // Perform parsing according to the rules above
          for (int i = 0; i < parsableString.length(); i++) {
              if (debugging) {
                  out.println();
              }
              if (debugging) {
                  out.println("parsing - index number " + i + ", active char: '"
                          + parsableString.getActiveChar() + "' char string index: " + parsableString.index
                          + " number of chars since last free-range state: " + numberOfParsedCharactersRead_SinceLastFreePassState);
              }
              if (debugging) {
                  out.println("parsing - state: " + runnerState.automatonStateNumber + " '"
                          + runnerState.character + "' - no of free-pass chars read: " + numberOfFreePassCharactersRead_SinceLastFreePassState);
              }
              if (debugging) {
                  out.println("parsing - hasPerformedFreeRangeMovement: " + hasPerformedFreeRangeMovement);
              }
              if (runnerState.nextState == null) {
                  if (debugging) {
                      out.println("parsing - runnerState.nextState == null");
                  }
  
                  // If there are no subsequent state (final state) and the state represents '*' - acceptance!
                  if (isFreeRangeCharacter(runnerState.character)) {
  
                      // Special free-range skipping check
                      if (hasPerformedFreeRangeMovement) {
                          if (parsableString.reachedEndOfString()) {
                              if (numberOfFreePassCharactersRead_SinceLastFreePassState > numberOfParsedCharactersRead_SinceLastFreePassState) {
                                  if (debugging) {
                                      out.println(
                                              "no subsequent state (final state) and the state represents '*' - end of parsing string, but not enough characters read - rejection!");
                                  }
                                  return false;
                              }
                              else {
                                  if (debugging) {
                                      out.println(
                                              "no subsequent state (final state) and the state represents '*' - end of parsing string and enough characters read - acceptance!");
                                  }
                                  return true;
                              }
                          }
                          else {
                              if (numberOfFreePassCharactersRead_SinceLastFreePassState > numberOfParsedCharactersRead_SinceLastFreePassState) {
                                  if (debugging) {
                                      out.println(
                                              "no subsequent state (final state) and the state represents '*' - not the end of parsing string and not enough characters read - read next character");
                                  }
                                  parsableString.index++;
                                  numberOfParsedCharactersRead_SinceLastFreePassState++;
                              }
                              else {
                                  if (debugging) {
                                      out.println(
                                              "no subsequent state (final state) and the state represents '*' - not the end of parsing string, but enough characters read - acceptance!");
                                  }
                                  return true;
                              }
                          }
                      }
                      else {
                          if (debugging) {
                              out.println("no subsequent state (final state) and the state represents '*' - no skipping performed - acceptance!");
                          }
                          return true;
                      }
                  }
  
                  // If there are no subsequent state (final state) and no skipping has been performed and the end of the string to test is reached - acceptance!
                  else if (parsableString.reachedEndOfString()) {
  
                      // Special free-range skipping check
                      if ((hasPerformedFreeRangeMovement)
                              && (numberOfFreePassCharactersRead_SinceLastFreePassState > numberOfParsedCharactersRead_SinceLastFreePassState)) {
                          if (debugging) {
                              out.println(
                                      "no subsequent state (final state) and skipping has been performed and end of parsing string, but not enough characters read - rejection!");
                          }
                          return false;
                      }
                      if (debugging) {
                          out.println("no subsequent state (final state) and the end of the string to test is reached - acceptance!");
                      }
                      return true;
                  }
                  else {
                      if (debugging) {
                          out.println("parsing - escaping process...");
                      }
                  }
              }
              else {
                  if (debugging) {
                      out.println("parsing - runnerState.nextState != null");
                  }
  
                  // Special Case:
                  // If this state represents '*' - go to the rightmost state representing '?'.
                  //    This state will act as an '*' - except that you only can go to the next state or accept the string, if and only if the number of '?' read are equal or less than the number of character read from the parsing string.
                  if (isFreeRangeCharacter(runnerState.character)) {
                      numberOfFreePassCharactersRead_SinceLastFreePassState = 0;
                      numberOfParsedCharactersRead_SinceLastFreePassState = 0;
                      WildcardStringParserState freeRangeRunnerState = runnerState.nextState;
  
                      while ((freeRangeRunnerState != null) && (isFreePassCharacter(freeRangeRunnerState.character))) {
                          runnerState = freeRangeRunnerState;
                          hasPerformedFreeRangeMovement = true;
                          numberOfFreePassCharactersRead_SinceLastFreePassState++;
                          freeRangeRunnerState = freeRangeRunnerState.nextState;
                      }
  
                      // Special Case: if the mask is at the end
                      if (runnerState.nextState == null) {
                          if (debugging) {
                              out.println();
                          }
                          if (debugging) {
                              out.println("parsing - index number " + i + ", active char: '"
                                      + parsableString.getActiveChar() + "' char string index: " + parsableString.index
                                      + " number of chars since last free-range state: " + numberOfParsedCharactersRead_SinceLastFreePassState);
                          }
                          if (debugging) {
                              out.println("parsing - state: " + runnerState.automatonStateNumber + " '"
                                      + runnerState.character + "' - no of free-pass chars read: " + numberOfFreePassCharactersRead_SinceLastFreePassState);
                          }
                          if (debugging) {
                              out.println("parsing - hasPerformedFreeRangeMovement: "
                                      + hasPerformedFreeRangeMovement);
                          }
                          if ((hasPerformedFreeRangeMovement)
                                  && (numberOfFreePassCharactersRead_SinceLastFreePassState >= numberOfParsedCharactersRead_SinceLastFreePassState)) {
                              return true;
                          }
                          else {
                              return false;
                          }
                      }
                  }
  
                  // If the next state represents '*' - go to this next state
                  if (isFreeRangeCharacter(runnerState.nextState.character)) {
                      runnerState = runnerState.nextState;
                      parsableString.index++;
                      numberOfParsedCharactersRead_SinceLastFreePassState++;
                  }
  
                  // If the next state represents '?' - go to this next state
                  else if (isFreePassCharacter(runnerState.nextState.character)) {
                      runnerState = runnerState.nextState;
                      parsableString.index++;
                      numberOfFreePassCharactersRead_SinceLastFreePassState++;
                      numberOfParsedCharactersRead_SinceLastFreePassState++;
                  }
  
                  // If the next state represents the same character as the next character in the string to test - go to this next state
                  else if ((!parsableString.reachedEndOfString()) && (runnerState.nextState.character == parsableString.getSubsequentChar())) {
                      runnerState = runnerState.nextState;
                      parsableString.index++;
                      numberOfParsedCharactersRead_SinceLastFreePassState++;
                  }
  
                  // If the next character in the string to test does not coincide with the next state - go to the last state representing '*'. If there are none - rejection!
                  else if (runnerState.lastFreeRangeState != null) {
                      runnerState = runnerState.lastFreeRangeState;
                      parsableString.index++;
                      numberOfParsedCharactersRead_SinceLastFreePassState++;
                  }
                  else {
                      if (debugging) {
                          out.println("the next state does not represent the same character as the next character in the string to test, and there are no last-free-range-state - rejection!");
                      }
                      return false;
                  }
              }
          }
          if (debugging) {
              out.println("finished reading parsing string and not at any final state - rejection!");
          }
          return false;
      }