private int classifyTag() {
        try {
            char ch = document.getChar(cNextPos++);
            cNewLines = 0;

            // processing instruction?
            if ('?' == ch) {
                boolean piFlag = false;
                while (cNextPos < fRangeEnd) {
                    ch = document.getChar(cNextPos++);
                    if (('>' == ch) && piFlag)
                        return PI_TAG;
                    piFlag = ('?' == ch);
                }
                return EOR_TAG;
            }

            // comment?
            if ('!' == ch) {
                cNextPos++; // must be '-' but we don't care if not
                cNextPos++; // must be '-' but we don't care if not
                int commEnd = 0;
                while (cNextPos < fRangeEnd) {
                    ch = document.getChar(cNextPos++);
                    if (('>' == ch) && (commEnd >= 2))
                        return COMMENT_TAG;
                    if (('\n' == ch) || ('\r' == ch)) {
                        if ((ch == cLastNLChar) || (' ' == cLastNLChar)) {
                            cNewLines++;
                            cLastNLChar = ch;
                        }
                    }
                    if ('-' == ch) {
                        commEnd++;
                    } else {
                        commEnd = 0;
                    }
                }
                return EOR_TAG;
            }

            // consume whitespaces
            while ((' ' == ch) || ('\t' == ch) || ('\n' == ch) || ('\r' == ch)) {
                ch = document.getChar(cNextPos++);
                if (cNextPos > fRangeEnd)
                    return EOR_TAG;
            }

            // end tag?
            if ('/' == ch) {
                while (cNextPos < fRangeEnd) {
                    ch = document.getChar(cNextPos++);
                    if ('>' == ch) {
                        cNewLines += eatToEndOfLine();
                        return END_TAG;
                    }
                    if ('"' == ch) {
                        ch = document.getChar(cNextPos++);
                        while ((cNextPos < fRangeEnd) && ('"' != ch)) {
                            ch = document.getChar(cNextPos++);
                        }
                    } else if ('\'' == ch) {
                        ch = document.getChar(cNextPos++);
                        while ((cNextPos < fRangeEnd) && ('\'' != ch)) {
                            ch = document.getChar(cNextPos++);
                        }
                    }
                }
                return EOR_TAG;
            }

            // start tag or leaf tag?
            while (cNextPos < fRangeEnd) {
                ch = document.getChar(cNextPos++);
                // end tag?
                s:
                switch (ch) {
                    case '/':
                        while (cNextPos < fRangeEnd) {
                            ch = document.getChar(cNextPos++);
                            if ('>' == ch) {
                                cNewLines += eatToEndOfLine();
                                return LEAF_TAG;
                            }
                        }
                        return EOR_TAG;
                    case '"':
                        while (cNextPos < fRangeEnd) {
                            ch = document.getChar(cNextPos++);
                            if ('"' == ch)
                                break s;
                        }
                        return EOR_TAG;
                    case '\'':
                        while (cNextPos < fRangeEnd) {
                            ch = document.getChar(cNextPos++);
                            if ('\'' == ch)
                                break s;
                        }
                        return EOR_TAG;
                    case '>':
                        cNewLines += eatToEndOfLine();
                        return START_TAG;
                    default:
                        break;
                }

            }
            return EOR_TAG;

        } catch (BadLocationException e) {
            // should not happen, but we treat it as end of range
            return EOR_TAG;
        }
    }
classsifies a tag: <br />
&lt;?...?&gt;: {@link #PI_TAG} <br />
&lt;!...--&gt;: {@link #COMMENT_TAG} <br />
&lt;...&gt;: {@link #START_TAG} <br />
&lt;.../&gt;: {@link #LEAF_TAG} <br />
&lt;/...&gt;: {@link #END_TAG} <br />
&lt;...: {@link #EOR_TAG} (end of range reached before closing &gt; is
found). <br />
when this method is called, {@link #cNextPos} must point to the character
after &lt;, when it returns, it points to the character after &gt; or
after the range. About syntax errors: this method is not a validator, it
is useful. Side effect: writes number of found newLines to
{@link #cNewLines}.

@return the tag classification
plugins/org.jkiss.dbeaver.ui.editors.xml/src/org/jkiss/dbeaver/ui/editors/xml/XMLReconcilingStrategy.java