private int createSuccessors(bool Skip, State p1)
        {
            //State upState = tempState1.Initialize(null);
            StateRef upState   = tempStateRef2;
            State    tempState = tempState1.Initialize(Heap);

            // PPM_CONTEXT* pc=MinContext, * UpBranch=FoundState->Successor;
            PPMContext pc = tempPPMContext1.Initialize(Heap);

            pc.Address = minContext.Address;
            PPMContext upBranch = tempPPMContext2.Initialize(Heap);

            upBranch.Address = foundState.GetSuccessor();

            // STATE * p, * ps[MAX_O], ** pps=ps;
            State p   = tempState2.Initialize(Heap);
            int   pps = 0;

            bool noLoop = false;

            if (!Skip)
            {
                ps[pps++] = foundState.Address; // *pps++ = FoundState;
                if (pc.getSuffix() == 0)
                {
                    noLoop = true;
                }
            }
            if (!noLoop)
            {
                bool loopEntry = false;
                if (p1.Address != 0)
                {
                    p.Address  = p1.Address;
                    pc.Address = pc.getSuffix(); // =pc->Suffix;
                    loopEntry  = true;
                }
                do
                {
                    if (!loopEntry)
                    {
                        pc.Address = pc.getSuffix(); // pc=pc->Suffix;
                        if (pc.NumStats != 1)
                        {
                            p.Address = pc.FreqData.GetStats(); // p=pc->U.Stats
                            if (p.Symbol != foundState.Symbol)
                            {
                                do
                                {
                                    p.IncrementAddress();
                                }while (p.Symbol != foundState.Symbol);
                            }
                        }
                        else
                        {
                            p.Address = pc.getOneState().Address; // p=&(pc->OneState);
                        }
                    } // LOOP_ENTRY:
                    loopEntry = false;
                    if (p.GetSuccessor() != upBranch.Address)
                    {
                        pc.Address = p.GetSuccessor(); // =p->Successor;
                        break;
                    }
                    ps[pps++] = p.Address;
                }while (pc.getSuffix() != 0);
            } // NO_LOOP:
            if (pps == 0)
            {
                return(pc.Address);
            }
            upState.Symbol = Heap[upBranch.Address]; // UpState.Symbol=*(byte*)
            // UpBranch;
            // UpState.Successor=(PPM_CONTEXT*) (((byte*) UpBranch)+1);
            upState.SetSuccessor(upBranch.Address + 1); //TODO check if +1 necessary
            if (pc.NumStats != 1)
            {
                if (pc.Address <= subAlloc.PText)
                {
                    return(0);
                }
                p.Address = pc.FreqData.GetStats();
                if (p.Symbol != upState.Symbol)
                {
                    do
                    {
                        p.IncrementAddress();
                    }while (p.Symbol != upState.Symbol);
                }
                int cf = p.Freq - 1;
                int s0 = pc.FreqData.SummFreq - pc.NumStats - cf;
                // UpState.Freq=1+((2*cf <= s0)?(5*cf > s0):((2*cf+3*s0-1)/(2*s0)));
                upState.Freq = 1 + ((2 * cf <= s0) ? (5 * cf > s0 ? 1 : 0) : ((2 * cf + 3 * s0 - 1) / (2 * s0)));
            }
            else
            {
                upState.Freq = pc.getOneState().Freq; // UpState.Freq=pc->OneState.Freq;
            }
            do
            {
                // pc = pc->createChild(this,*--pps,UpState);
                tempState.Address = ps[--pps];
                pc.Address        = pc.createChild(this, tempState, upState);
                if (pc.Address == 0)
                {
                    return(0);
                }
            }while (pps != 0);
            return(pc.Address);
        }
        public virtual int decodeChar()
        {
            // Debug
            //subAlloc.dumpHeap();

            if (minContext.Address <= subAlloc.PText || minContext.Address > subAlloc.HeapEnd)
            {
                return(-1);
            }

            if (minContext.NumStats != 1)
            {
                if (minContext.FreqData.GetStats() <= subAlloc.PText || minContext.FreqData.GetStats() > subAlloc.HeapEnd)
                {
                    return(-1);
                }
                if (!minContext.decodeSymbol1(this))
                {
                    return(-1);
                }
            }
            else
            {
                minContext.decodeBinSymbol(this);
            }
            coder.Decode();
            while (foundState.Address == 0)
            {
                coder.AriDecNormalize();
                do
                {
                    orderFall++;
                    minContext.Address = minContext.getSuffix(); // =MinContext->Suffix;
                    if (minContext.Address <= subAlloc.PText || minContext.Address > subAlloc.HeapEnd)
                    {
                        return(-1);
                    }
                }while (minContext.NumStats == numMasked);
                if (!minContext.decodeSymbol2(this))
                {
                    return(-1);
                }
                coder.Decode();
            }
            int Symbol = foundState.Symbol;

            if ((orderFall == 0) && foundState.GetSuccessor() > subAlloc.PText)
            {
                // MinContext=MaxContext=FoundState->Successor;
                int addr = foundState.GetSuccessor();
                minContext.Address = addr;
                maxContext.Address = addr;
            }
            else
            {
                updateModel();
                //this.foundState.Address=foundState.Address);//TODO just 4 debugging
                if (escCount == 0)
                {
                    clearMask();
                }
            }
            coder.AriDecNormalize(); // ARI_DEC_NORMALIZE(Coder.code,Coder.low,Coder.range,Coder.UnpackRead);
            return(Symbol);
        }