docs: @Nonnull
    private EMarkToken _getToken (final String sIn, final int nPos)
    {
      final char c0 = nPos > 0 ? _whitespaceToSpace (sIn.charAt (nPos - 1)) : ' ';
      final char c = _whitespaceToSpace (sIn.charAt (nPos));
      final char c1 = nPos + 1 < sIn.length () ? _whitespaceToSpace (sIn.charAt (nPos + 1)) : ' ';
      final char c2 = nPos + 2 < sIn.length () ? _whitespaceToSpace (sIn.charAt (nPos + 2)) : ' ';
      final char c3 = nPos + 3 < sIn.length () ? _whitespaceToSpace (sIn.charAt (nPos + 3)) : ' ';
  
      switch (c)
      {
        case '*':
          if (c1 == '*')
          {
            return c0 != ' ' || c2 != ' ' ? EMarkToken.STRONG_STAR : EMarkToken.EM_STAR;
          }
          return c0 != ' ' || c1 != ' ' ? EMarkToken.EM_STAR : EMarkToken.NONE;
        case '_':
          if (c1 == '_')
          {
            return c0 != ' ' || c2 != ' ' ? EMarkToken.STRONG_UNDERSCORE : EMarkToken.EM_UNDERSCORE;
          }
          if (m_bUseExtensions)
          {
            return Character.isLetterOrDigit (c0) &&
                   c0 != '_' &&
                   Character.isLetterOrDigit (c1) ? EMarkToken.NONE : EMarkToken.EM_UNDERSCORE;
          }
          return c0 != ' ' || c1 != ' ' ? EMarkToken.EM_UNDERSCORE : EMarkToken.NONE;
        case '~':
          if (m_bUseExtensions && c1 == '~')
          {
            return EMarkToken.STRIKE;
          }
          return EMarkToken.NONE;
        case '!':
          if (c1 == '[')
            return EMarkToken.IMAGE;
          return EMarkToken.NONE;
        case '[':
          if (m_bUseExtensions && c1 == '[')
            return EMarkToken.X_LINK_OPEN;
          return EMarkToken.LINK;
        case ']':
          if (m_bUseExtensions && c1 == ']')
            return EMarkToken.X_LINK_CLOSE;
          return EMarkToken.NONE;
        case '`':
          return c1 == '`' ? EMarkToken.CODE_DOUBLE : EMarkToken.CODE_SINGLE;
        case '\\':
          if (MarkdownHelper.isEscapeChar (c1))
            return EMarkToken.ESCAPE;
          return EMarkToken.NONE;
        case '<':
          if (m_bUseExtensions && c1 == '<')
            return EMarkToken.X_LAQUO;
          return EMarkToken.HTML;
        case '&':
          return EMarkToken.ENTITY;
        default:
          if (m_bUseExtensions)
          {
            switch (c)
            {
              case '-':
                if (c1 == '-')
                  return c2 == '-' ? EMarkToken.X_MDASH : EMarkToken.X_NDASH;
                break;
              case '^':
                return c0 == '^' || c1 == '^' ? EMarkToken.NONE : EMarkToken.SUPER;
              case '>':
                if (c1 == '>')
                  return EMarkToken.X_RAQUO;
                break;
              case '.':
                if (c1 == '.' && c2 == '.')
                  return EMarkToken.X_HELLIP;
                break;
              case '(':
                if (c1 == 'C' && c2 == ')')
                  return EMarkToken.X_COPY;
                if (c1 == 'R' && c2 == ')')
                  return EMarkToken.X_REG;
                if (c1 == 'T' & c2 == 'M' & c3 == ')')
                  return EMarkToken.X_TRADE;
                break;
              case '"':
                if (!Character.isLetterOrDigit (c0) && c1 != ' ')
                  return EMarkToken.X_LDQUO;
                if (c0 != ' ' && !Character.isLetterOrDigit (c1))
                  return EMarkToken.X_RDQUO;
                break;
            }
          }
          return EMarkToken.NONE;
      }
    }