private static void handleLinkAndInlineGroupMatch(string text, InlineMarkupMatch openMatch, InlineMarkupMatch closeMatch,
            Stack<InlineMarkupMatch> matchStack, ref int nextMatchIndex,
            ref string newText, ref string closeMarks)
        {
            if (closeMatch.type == KARAS.InlineMarkupTypeLinkOpen
                || closeMatch.type == KARAS.InlineMarkupTypeInlineGroupOpen)
            {
                matchStack.Push(closeMatch);
                nextMatchIndex = closeMatch.index + closeMatch.marks.Length;
                return;
            }

            if (openMatch == null)
            {
                nextMatchIndex = closeMatch.index + closeMatch.marks.Length;
                return;
            }

            int markedupTextIndex = openMatch.index + openMatch.marks.Length;
            string markedupText = text.Substring
                (markedupTextIndex, closeMatch.index - markedupTextIndex);
            string openMarks = KARAS.removeWhiteSpace(openMatch.marks);
            closeMarks = KARAS.removeWhiteSpace(closeMatch.marks);

            if (closeMatch.type == KARAS.InlineMarkupTypeLinkClose)
            {
                KARAS.constructLinkText
                    (markedupText, ref newText, ref openMarks, ref closeMarks);
            }
            else
            {
                KARAS.constructInlineGroupText
                    (markedupText, ref newText, ref openMarks, ref closeMarks);
            }

            if (openMarks.Length > 1)
            {
                openMatch.marks = openMarks;
            }
            else
            {
                while (true)
                {
                    if (matchStack.Pop().type == openMatch.type)
                    {
                        break;
                    }
                }
            }

            nextMatchIndex = -1;
            return;
        }
        private static void handleBasicInlineMarkupMatch(string text, InlineMarkupMatch openMatch, InlineMarkupMatch closeMatch,
            Stack<InlineMarkupMatch> matchStack, ref int nextMatchIndex,
            ref string newText, ref string closeMarks)
        {
            if (openMatch == null)
            {
                matchStack.Push(closeMatch);
                nextMatchIndex = closeMatch.index + closeMatch.marks.Length;
                return;
            }

            int markedupTextIndex = openMatch.index + openMatch.marks.Length;
            string markedupText = text.Substring
                (markedupTextIndex, closeMatch.index - markedupTextIndex).Trim();

            if (openMatch.type <= KARAS.InlineMarkupTypeSupRuby
                && openMatch.marks.Length >= 3 && closeMatch.marks.Length >= 3)
            {
                KARAS.constructSecondInlineMarkupText
                    (markedupText, openMatch, closeMatch, ref newText, ref closeMarks);
            }
            else
            {
                KARAS.constructFirstInlineMarkupText
                    (markedupText, openMatch, closeMatch, ref newText, ref closeMarks);
            }

            while (true)
            {
                if (matchStack.Pop().type == closeMatch.type)
                {
                    break;
                }
            }

            nextMatchIndex = -1;
            return;
        }
        private static InlineMarkupMatch constructInlineMarkupMatch(int index, string marks)
        {
            InlineMarkupMatch inlineMarkupMatch = new InlineMarkupMatch();

            for (int i = 0; i < KARAS.InlineMarkupSets.Length; i += 1)
            {
                if (marks[0] == KARAS.InlineMarkupSets[i][0][0])
                {
                    inlineMarkupMatch.type = i;
                    inlineMarkupMatch.index = index;
                    inlineMarkupMatch.marks = marks;
                    break;
                }
            }

            return inlineMarkupMatch;
        }
        private static void constructSecondInlineMarkupText(string markedupText, InlineMarkupMatch openMatch, InlineMarkupMatch closeMatch,
             ref string newText, ref string closeMarks)
        {
            string[] inlineMarkupSet = KARAS.InlineMarkupSets[openMatch.type];
            string openMarks = openMatch.marks.Remove(0, 3);
            closeMarks = closeMatch.marks.Remove(0, 3);
            string openTag = "";
            string closeTag = "";

            if (openMatch.type == KARAS.InlineMarkupTypeSupRuby)
            {
                openTag = "<ruby>";
                closeTag = "</ruby>";

                bool hasSpecialOption = false;
                string[] markedupTexts = KARAS.splitOptions(markedupText, ref hasSpecialOption);
                markedupText = markedupTexts[0];

                for (int i = 1; i < markedupTexts.Length; i += 2)
                {
                    markedupText += "<rp> (</rp><rt>" + markedupTexts[i] + "</rt><rp>) </rp>";

                    if (i + 1 < markedupTexts.Length)
                    {
                        markedupText += markedupTexts[i + 1];
                    }
                }
            }
            else
            {
                openTag = "<" + inlineMarkupSet[2] + ">";
                closeTag = "</" + inlineMarkupSet[2] + ">";

                if (openMatch.type == KARAS.InlineMarkupTypeDefAbbr)
                {
                    openTag = "<" + inlineMarkupSet[1] + ">" + openTag;
                    closeTag = closeTag + "</" + inlineMarkupSet[1] + ">";
                }

                if (openMatch.type == KARAS.InlineMarkupKbdSamp
                    || openMatch.type == KARAS.InlineMarkupVarCode)
                {
                    markedupText = KARAS.escapeHTMLSpecialCharacters(markedupText);
                }
            }

            newText = openMarks + openTag + markedupText + closeTag + closeMarks;
        }
        private static void constructFirstInlineMarkupText(string markedupText, InlineMarkupMatch openMatch, InlineMarkupMatch closeMatch,
             ref string newText, ref string closeMarks)
        {
            string[] inlineMarkupSet = KARAS.InlineMarkupSets[openMatch.type];
            string openMarks = openMatch.marks.Remove(0, 2);
            closeMarks = closeMatch.marks.Remove(0, 2);
            string openTag = "<" + inlineMarkupSet[1] + ">";
            string closeTag = "</" + inlineMarkupSet[1] + ">";

            if (openMatch.type == KARAS.InlineMarkupVarCode
                || openMatch.type == KARAS.InlineMarkupKbdSamp)
            {
                markedupText = KARAS.escapeHTMLSpecialCharacters(markedupText);
            }

            newText = openMarks + openTag + markedupText + closeTag + closeMarks;
        }