private bool EvalChar(Interpreter.Mode mode, ref int ptr, ref int pc, bool multi)
        {
            bool flag = false;
            char c    = '\0';
            bool flag3;

            for (;;)
            {
                ushort  num     = this.program[pc];
                OpCode  opCode  = (OpCode)(num & 255);
                OpFlags opFlags = (OpFlags)(num & 65280);
                pc++;
                bool flag2 = (ushort)(opFlags & OpFlags.IgnoreCase) != 0;
                if (!flag)
                {
                    if ((ushort)(opFlags & OpFlags.RightToLeft) != 0)
                    {
                        if (ptr <= 0)
                        {
                            break;
                        }
                        c = this.text[--ptr];
                    }
                    else
                    {
                        if (ptr >= this.text_end)
                        {
                            return(false);
                        }
                        c = this.text[ptr++];
                    }
                    if (flag2)
                    {
                        c = char.ToLower(c);
                    }
                    flag = true;
                }
                flag3 = ((ushort)(opFlags & OpFlags.Negate) != 0);
                switch (opCode)
                {
                case OpCode.False:
                    return(false);

                case OpCode.True:
                    return(true);

                case OpCode.Character:
                    if (c == (char)this.program[pc++])
                    {
                        goto Block_7;
                    }
                    break;

                case OpCode.Category:
                    if (CategoryUtils.IsCategory((Category)this.program[pc++], c))
                    {
                        goto Block_8;
                    }
                    break;

                case OpCode.NotCategory:
                    if (!CategoryUtils.IsCategory((Category)this.program[pc++], c))
                    {
                        goto Block_9;
                    }
                    break;

                case OpCode.Range:
                {
                    int num2 = (int)this.program[pc++];
                    int num3 = (int)this.program[pc++];
                    if (num2 <= (int)c && (int)c <= num3)
                    {
                        goto Block_11;
                    }
                    break;
                }

                case OpCode.Set:
                {
                    int num4 = (int)this.program[pc++];
                    int num5 = (int)this.program[pc++];
                    int num6 = pc;
                    pc += num5;
                    int num7 = (int)c - num4;
                    if (num7 >= 0 && num7 < num5 << 4)
                    {
                        if (((int)this.program[num6 + (num7 >> 4)] & 1 << (num7 & 15)) != 0)
                        {
                            goto Block_13;
                        }
                    }
                    break;
                }
                }
                if (!multi)
                {
                    return(flag3);
                }
            }
            return(false);

Block_7:
            return(!flag3);

Block_8:
            return(!flag3);

Block_9:
            return(!flag3);

Block_11:
            return(!flag3);

Block_13:
            return(!flag3);
        }
        private bool Eval(Interpreter.Mode mode, ref int ref_ptr, int pc)
        {
            int num = ref_ptr;

            Interpreter.RepeatContext repeatContext;
            int start;
            int count;

            for (;;)
            {
                OpFlags opFlags;
                for (;;)
                {
                    ushort num2   = this.program[pc];
                    OpCode opCode = (OpCode)(num2 & 255);
                    opFlags = (OpFlags)(num2 & 65280);
                    switch (opCode)
                    {
                    case OpCode.False:
                        goto IL_4B8;

                    case OpCode.True:
                        goto IL_4BD;

                    case OpCode.Position:
                        if (!this.IsPosition((Position)this.program[pc + 1], num))
                        {
                            goto Block_44;
                        }
                        pc += 2;
                        break;

                    case OpCode.String:
                    {
                        bool flag  = (ushort)(opFlags & OpFlags.RightToLeft) != 0;
                        bool flag2 = (ushort)(opFlags & OpFlags.IgnoreCase) != 0;
                        int  num3  = (int)this.program[pc + 1];
                        if (flag)
                        {
                            num -= num3;
                            if (num < 0)
                            {
                                goto Block_46;
                            }
                        }
                        else if (num + num3 > this.text_end)
                        {
                            goto Block_47;
                        }
                        pc += 2;
                        for (int i = 0; i < num3; i++)
                        {
                            char c = this.text[num + i];
                            if (flag2)
                            {
                                c = char.ToLower(c);
                            }
                            if (c != (char)this.program[pc++])
                            {
                                goto Block_49;
                            }
                        }
                        if (!flag)
                        {
                            num += num3;
                        }
                        break;
                    }

                    case OpCode.Reference:
                    {
                        bool flag3       = (ushort)(opFlags & OpFlags.RightToLeft) != 0;
                        bool flag4       = (ushort)(opFlags & OpFlags.IgnoreCase) != 0;
                        int  lastDefined = this.GetLastDefined((int)this.program[pc + 1]);
                        if (lastDefined < 0)
                        {
                            goto Block_52;
                        }
                        int index  = this.marks[lastDefined].Index;
                        int length = this.marks[lastDefined].Length;
                        if (flag3)
                        {
                            num -= length;
                            if (num < 0)
                            {
                                goto Block_54;
                            }
                        }
                        else if (num + length > this.text_end)
                        {
                            goto Block_55;
                        }
                        pc += 2;
                        if (flag4)
                        {
                            for (int j = 0; j < length; j++)
                            {
                                if (char.ToLower(this.text[num + j]) != char.ToLower(this.text[index + j]))
                                {
                                    goto Block_57;
                                }
                            }
                        }
                        else
                        {
                            for (int k = 0; k < length; k++)
                            {
                                if (this.text[num + k] != this.text[index + k])
                                {
                                    goto Block_59;
                                }
                            }
                        }
                        if (!flag3)
                        {
                            num += length;
                        }
                        break;
                    }

                    case OpCode.Character:
                    case OpCode.Category:
                    case OpCode.NotCategory:
                    case OpCode.Range:
                    case OpCode.Set:
                        if (!this.EvalChar(mode, ref num, ref pc, false))
                        {
                            goto Block_61;
                        }
                        break;

                    case OpCode.In:
                    {
                        int num4 = pc + (int)this.program[pc + 1];
                        pc += 2;
                        if (!this.EvalChar(mode, ref num, ref pc, true))
                        {
                            goto Block_62;
                        }
                        pc = num4;
                        break;
                    }

                    case OpCode.Open:
                        this.Open((int)this.program[pc + 1], num);
                        pc += 2;
                        break;

                    case OpCode.Close:
                        this.Close((int)this.program[pc + 1], num);
                        pc += 2;
                        break;

                    case OpCode.Balance:
                        goto IL_7DB;

                    case OpCode.BalanceStart:
                    {
                        int ptr = num;
                        if (!this.Eval(Interpreter.Mode.Match, ref num, pc + 5))
                        {
                            goto Block_63;
                        }
                        if (!this.Balance((int)this.program[pc + 1], (int)this.program[pc + 2], this.program[pc + 3] == 1, ptr))
                        {
                            goto Block_65;
                        }
                        pc += (int)this.program[pc + 4];
                        break;
                    }

                    case OpCode.IfDefined:
                    {
                        int lastDefined2 = this.GetLastDefined((int)this.program[pc + 2]);
                        if (lastDefined2 < 0)
                        {
                            pc += (int)this.program[pc + 1];
                        }
                        else
                        {
                            pc += 3;
                        }
                        break;
                    }

                    case OpCode.Sub:
                        if (!this.Eval(Interpreter.Mode.Match, ref num, pc + 2))
                        {
                            goto Block_67;
                        }
                        pc += (int)this.program[pc + 1];
                        break;

                    case OpCode.Test:
                    {
                        int cp   = this.Checkpoint();
                        int num5 = num;
                        if (this.Eval(Interpreter.Mode.Match, ref num5, pc + 3))
                        {
                            pc += (int)this.program[pc + 1];
                        }
                        else
                        {
                            this.Backtrack(cp);
                            pc += (int)this.program[pc + 2];
                        }
                        break;
                    }

                    case OpCode.Branch:
                        goto IL_88A;

                    case OpCode.Jump:
                        pc += (int)this.program[pc + 1];
                        break;

                    case OpCode.Repeat:
                        goto IL_8EE;

                    case OpCode.Until:
                        goto IL_957;

                    case OpCode.FastRepeat:
                        goto IL_C6F;

                    case OpCode.Anchor:
                        goto IL_96;

                    case OpCode.Info:
                        goto IL_FE9;
                    }
                }
                for (;;)
                {
IL_88A:
                    int cp2 = this.Checkpoint();
                    if (this.Eval(Interpreter.Mode.Match, ref num, pc + 2))
                    {
                        break;
                    }
                    this.Backtrack(cp2);
                    pc += (int)this.program[pc + 1];
                    if ((this.program[pc] & 255) == 0)
                    {
                        goto Block_70;
                    }
                }
IL_FF3:
                ref_ptr = num;
                if (mode == Interpreter.Mode.Match)
                {
                    return(true);
                }
                if (mode != Interpreter.Mode.Count)
                {
                    break;
                }
                this.fast.Count++;
                if (this.fast.IsMaximum || (this.fast.IsLazy && this.fast.IsMinimum))
                {
                    return(true);
                }
                pc = this.fast.Expression;
                continue;
IL_96:
                int num6 = (int)this.program[pc + 1];
                int    num7    = (int)this.program[pc + 2];
                bool   flag5   = (ushort)(opFlags & OpFlags.RightToLeft) != 0;
                int    num8    = (!flag5) ? (num + num7) : (num - num7);
                int    num9    = this.text_end - this.match_min + num7;
                int    num10   = 0;
                OpCode opCode2 = (OpCode)(this.program[pc + 3] & 255);
                if (opCode2 == OpCode.Position && num6 == 6)
                {
                    switch (this.program[pc + 4])
                    {
                    case 2:
                        if (flag5 || num7 == 0)
                        {
                            if (flag5)
                            {
                                num = num7;
                            }
                            if (this.TryMatch(ref num, pc + num6))
                            {
                                goto IL_FF3;
                            }
                        }
                        break;

                    case 3:
                        if (num8 == 0)
                        {
                            num = 0;
                            if (this.TryMatch(ref num, pc + num6))
                            {
                                goto IL_FF3;
                            }
                            num8++;
                        }
                        while ((flag5 && num8 >= 0) || (!flag5 && num8 <= num9))
                        {
                            if (num8 == 0 || this.text[num8 - 1] == '\n')
                            {
                                if (flag5)
                                {
                                    num = ((num8 != num9) ? (num8 + num7) : num8);
                                }
                                else
                                {
                                    num = ((num8 != 0) ? (num8 - num7) : num8);
                                }
                                if (this.TryMatch(ref num, pc + num6))
                                {
                                    goto IL_FF3;
                                }
                            }
                            if (flag5)
                            {
                                num8--;
                            }
                            else
                            {
                                num8++;
                            }
                        }
                        break;

                    case 4:
                        if (num8 == this.scan_ptr)
                        {
                            num = ((!flag5) ? (this.scan_ptr - num7) : (this.scan_ptr + num7));
                            if (this.TryMatch(ref num, pc + num6))
                            {
                                goto IL_FF3;
                            }
                        }
                        break;
                    }
                    break;
                }
                if (this.qs != null || (opCode2 == OpCode.String && num6 == (int)(6 + this.program[pc + 4])))
                {
                    bool flag6 = (this.program[pc + 3] & 1024) != 0;
                    if (this.qs == null)
                    {
                        bool   ignore  = (this.program[pc + 3] & 512) != 0;
                        string @string = this.GetString(pc + 3);
                        this.qs = new QuickSearch(@string, ignore, flag6);
                    }
                    while ((flag5 && num8 >= num10) || (!flag5 && num8 <= num9))
                    {
                        if (flag6)
                        {
                            num8 = this.qs.Search(this.text, num8, num10);
                            if (num8 != -1)
                            {
                                num8 += this.qs.Length;
                            }
                        }
                        else
                        {
                            num8 = this.qs.Search(this.text, num8, num9);
                        }
                        if (num8 < 0)
                        {
                            break;
                        }
                        num = ((!flag6) ? (num8 - num7) : (num8 + num7));
                        if (this.TryMatch(ref num, pc + num6))
                        {
                            goto IL_FF3;
                        }
                        if (flag6)
                        {
                            num8 -= 2;
                        }
                        else
                        {
                            num8++;
                        }
                    }
                    break;
                }
                if (opCode2 == OpCode.True)
                {
                    while ((flag5 && num8 >= num10) || (!flag5 && num8 <= num9))
                    {
                        num = num8;
                        if (this.TryMatch(ref num, pc + num6))
                        {
                            goto IL_FF3;
                        }
                        if (flag5)
                        {
                            num8--;
                        }
                        else
                        {
                            num8++;
                        }
                    }
                    break;
                }
                while ((flag5 && num8 >= num10) || (!flag5 && num8 <= num9))
                {
                    num = num8;
                    if (this.Eval(Interpreter.Mode.Match, ref num, pc + 3))
                    {
                        num = ((!flag5) ? (num8 - num7) : (num8 + num7));
                        if (this.TryMatch(ref num, pc + num6))
                        {
                            goto IL_FF3;
                        }
                    }
                    if (flag5)
                    {
                        num8--;
                    }
                    else
                    {
                        num8++;
                    }
                }
                break;
IL_4BD:
IL_7DB:
                goto IL_FF3;
IL_8EE:
                this.repeat = new Interpreter.RepeatContext(this.repeat, this.ReadProgramCount(pc + 2), this.ReadProgramCount(pc + 4), (ushort)(opFlags & OpFlags.Lazy) != 0, pc + 6);
                if (this.Eval(Interpreter.Mode.Match, ref num, pc + (int)this.program[pc + 1]))
                {
                    goto IL_FF3;
                }
                goto IL_941;
IL_957:
                repeatContext = this.repeat;
                if (this.deep == repeatContext)
                {
                    goto IL_FF3;
                }
                start = repeatContext.Start;
                count = repeatContext.Count;
                while (!repeatContext.IsMinimum)
                {
                    repeatContext.Count++;
                    repeatContext.Start = num;
                    this.deep           = repeatContext;
                    if (!this.Eval(Interpreter.Mode.Match, ref num, repeatContext.Expression))
                    {
                        goto Block_73;
                    }
                    if (this.deep != repeatContext)
                    {
                        goto IL_FF3;
                    }
                }
                if (num == repeatContext.Start)
                {
                    this.repeat = repeatContext.Previous;
                    this.deep   = null;
                    if (this.Eval(Interpreter.Mode.Match, ref num, pc + 1))
                    {
                        goto IL_FF3;
                    }
                    goto IL_A28;
                }
                else
                {
                    if (repeatContext.IsLazy)
                    {
                        for (;;)
                        {
                            this.repeat = repeatContext.Previous;
                            this.deep   = null;
                            int cp3 = this.Checkpoint();
                            if (this.Eval(Interpreter.Mode.Match, ref num, pc + 1))
                            {
                                break;
                            }
                            this.Backtrack(cp3);
                            this.repeat = repeatContext;
                            if (repeatContext.IsMaximum)
                            {
                                goto Block_80;
                            }
                            repeatContext.Count++;
                            repeatContext.Start = num;
                            this.deep           = repeatContext;
                            if (!this.Eval(Interpreter.Mode.Match, ref num, repeatContext.Expression))
                            {
                                goto Block_81;
                            }
                            if (this.deep != repeatContext)
                            {
                                break;
                            }
                            if (num == repeatContext.Start)
                            {
                                goto Block_83;
                            }
                        }
                        goto IL_FF3;
                    }
                    int count2 = this.stack.Count;
                    while (!repeatContext.IsMaximum)
                    {
                        int num11  = this.Checkpoint();
                        int value  = num;
                        int start2 = repeatContext.Start;
                        repeatContext.Count++;
                        repeatContext.Start = num;
                        this.deep           = repeatContext;
                        if (!this.Eval(Interpreter.Mode.Match, ref num, repeatContext.Expression))
                        {
                            repeatContext.Count--;
                            repeatContext.Start = start2;
                            this.Backtrack(num11);
                            break;
                        }
                        if (this.deep != repeatContext)
                        {
                            this.stack.Count = count2;
                            goto IL_FF3;
                        }
                        this.stack.Push(num11);
                        this.stack.Push(value);
                        if (num == repeatContext.Start)
                        {
                            break;
                        }
                    }
                    this.repeat = repeatContext.Previous;
                    for (;;)
                    {
                        this.deep = null;
                        if (this.Eval(Interpreter.Mode.Match, ref num, pc + 1))
                        {
                            break;
                        }
                        if (this.stack.Count == count2)
                        {
                            goto Block_88;
                        }
                        repeatContext.Count--;
                        num = this.stack.Pop();
                        this.Backtrack(this.stack.Pop());
                    }
                    this.stack.Count = count2;
                    goto IL_FF3;
                }
IL_C6F:
                this.fast       = new Interpreter.RepeatContext(this.fast, this.ReadProgramCount(pc + 2), this.ReadProgramCount(pc + 4), (ushort)(opFlags & OpFlags.Lazy) != 0, pc + 6);
                this.fast.Start = num;
                int cp4 = this.Checkpoint();
                pc += (int)this.program[pc + 1];
                ushort num12   = this.program[pc];
                int    num13   = -1;
                int    num14   = -1;
                int    num15   = 0;
                OpCode opCode3 = (OpCode)(num12 & 255);
                if (opCode3 == OpCode.Character || opCode3 == OpCode.String)
                {
                    OpFlags opFlags2 = (OpFlags)(num12 & 65280);
                    if ((ushort)(opFlags2 & OpFlags.Negate) == 0)
                    {
                        if (opCode3 == OpCode.String)
                        {
                            int num16 = 0;
                            if ((ushort)(opFlags2 & OpFlags.RightToLeft) != 0)
                            {
                                num16 = (int)(this.program[pc + 1] - 1);
                            }
                            num13 = (int)this.program[pc + 2 + num16];
                        }
                        else
                        {
                            num13 = (int)this.program[pc + 1];
                        }
                        if ((ushort)(opFlags2 & OpFlags.IgnoreCase) != 0)
                        {
                            num14 = (int)char.ToUpper((char)num13);
                        }
                        else
                        {
                            num14 = num13;
                        }
                        if ((ushort)(opFlags2 & OpFlags.RightToLeft) != 0)
                        {
                            num15 = -1;
                        }
                        else
                        {
                            num15 = 0;
                        }
                    }
                }
                if (this.fast.IsLazy)
                {
                    if (!this.fast.IsMinimum && !this.Eval(Interpreter.Mode.Count, ref num, this.fast.Expression))
                    {
                        goto Block_97;
                    }
                    for (;;)
                    {
                        int num17 = num + num15;
                        if (num13 < 0 || (num17 >= 0 && num17 < this.text_end && (num13 == (int)this.text[num17] || num14 == (int)this.text[num17])))
                        {
                            this.deep = null;
                            if (this.Eval(Interpreter.Mode.Match, ref num, pc))
                            {
                                break;
                            }
                        }
                        if (this.fast.IsMaximum)
                        {
                            goto Block_103;
                        }
                        this.Backtrack(cp4);
                        if (!this.Eval(Interpreter.Mode.Count, ref num, this.fast.Expression))
                        {
                            goto Block_104;
                        }
                    }
                    this.fast = this.fast.Previous;
                    goto IL_FF3;
                }
                else
                {
                    if (!this.Eval(Interpreter.Mode.Count, ref num, this.fast.Expression))
                    {
                        goto Block_105;
                    }
                    int num18;
                    if (this.fast.Count > 0)
                    {
                        num18 = (num - this.fast.Start) / this.fast.Count;
                    }
                    else
                    {
                        num18 = 0;
                    }
                    for (;;)
                    {
                        int num19 = num + num15;
                        if (num13 < 0 || (num19 >= 0 && num19 < this.text_end && (num13 == (int)this.text[num19] || num14 == (int)this.text[num19])))
                        {
                            this.deep = null;
                            if (this.Eval(Interpreter.Mode.Match, ref num, pc))
                            {
                                break;
                            }
                        }
                        this.fast.Count--;
                        if (!this.fast.IsMinimum)
                        {
                            goto Block_112;
                        }
                        num -= num18;
                        this.Backtrack(cp4);
                    }
                    this.fast = this.fast.Previous;
                    goto IL_FF3;
                }
            }
IL_4B8:
Block_44:
Block_46:
Block_47:
Block_49:
Block_52:
Block_54:
Block_55:
Block_57:
Block_59:
Block_61:
Block_62:
Block_63:
Block_65:
Block_67:
Block_70:
            goto IL_1067;
IL_941:
            this.repeat = this.repeat.Previous;
            goto IL_1067;
Block_73:
            repeatContext.Start = start;
            repeatContext.Count = count;
            goto IL_1067;
IL_A28:
            this.repeat = repeatContext;
Block_80:
            goto IL_1067;
Block_81:
            repeatContext.Start = start;
            repeatContext.Count = count;
Block_83:
            goto IL_1067;
Block_88:
            this.repeat = repeatContext;
            goto IL_1067;
Block_97:
            this.fast = this.fast.Previous;
            goto IL_1067;
Block_103:
            this.fast = this.fast.Previous;
            goto IL_1067;
Block_104:
            this.fast = this.fast.Previous;
            goto IL_1067;
Block_105:
            this.fast = this.fast.Previous;
            goto IL_1067;
Block_112:
            this.fast = this.fast.Previous;
IL_FE9:
IL_1067:
            if (mode == Interpreter.Mode.Match)
            {
                return(false);
            }
            if (mode != Interpreter.Mode.Count)
            {
                return(false);
            }
            if (!this.fast.IsLazy && this.fast.IsMinimum)
            {
                return(true);
            }
            ref_ptr = this.fast.Start;
            return(false);
        }