anchor.diff:   end;
    FreeAndNil(DFAStateCache);
    SetLength(DFAStackInstructions,0);
  +
  + SetLength(InstructionGenerations,0);
  +
  + SetLength(ThreadLists[0].Threads,0);
  + SetLength(ThreadLists[1].Threads,0);
  +
  + inherited Destroy;
  +end;
  +
  +function TFLREThreadLocalState.GetSatisfyFlags(const Position:longint):longword;
  +var PreviousPosition:longint;
  +    PreviousChar,CurrentChar:longword;
  +begin
  + result:=0;
  + if rfUTF8 in Instance.Flags then begin
  +  PreviousPosition:=Position;
  +  UTF8PtrDec(Input,InputLength,PreviousPosition);
  +  if (PreviousPosition>=0) and (PreviousPosition<=InputLength) then begin
  +   PreviousChar:=UTF8PtrCodeUnitGetCharFallback(Input,InputLength,PreviousPosition);
  +  end else begin
  +   PreviousChar:=0;
  +  end;
  +  if (Position>=0) and (Position<InputLength) then begin
  +   CurrentChar:=UTF8PtrCodeUnitGetCharFallback(Input,InputLength,Position);
  +  end else begin
  +   CurrentChar:=0;
  +  end;
  + end else begin
  +  PreviousPosition:=Position-1;
  +  if (PreviousPosition>=0) and (PreviousPosition<=InputLength) then begin
  +   PreviousChar:=byte(ansichar(Input[PreviousPosition]));
  +  end else begin
  +   PreviousChar:=0;
  +  end;
  +  if (Position>=0) and (Position<InputLength) then begin
  +   CurrentChar:=byte(ansichar(Input[Position]));
  +  end else begin
  +   CurrentChar:=0;
  +  end;
  + end;
  + if Position<=0 then begin
  +  result:=result or (sfEmptyBeginText or sfEmptyBeginLine);
  + end else begin
  +  case PreviousChar of
  +   $0a,$0d,$85,$2028,$2029:begin
  +    result:=result or sfEmptyBeginLine;
  +   end;
  +  end;
  + end;
  + if Position>=(InputLength-1) then begin
  +  result:=result or (sfEmptyEndText or sfEmptyEndLine);
  + end else begin
  +  case CurrentChar of
  +   $0a,$0d,$85,$2028,$2029:begin
  +    result:=result or sfEmptyEndLine;
  +   end;
  +  end;
  + end;
  + if InputLength>0 then begin
  +  if Position=0 then begin
  +   if Instance.IsWordChar(CurrentChar) then begin
  +    result:=result or sfEmptyWordBoundary;
  +   end;
  +  end else if Position>=InputLength then begin
  +   if Instance.IsWordChar(PreviousChar) then begin
  +    result:=result or sfEmptyWordBoundary;
  +   end;
  +  end else if Instance.IsWordChar(PreviousChar)<>Instance.IsWordChar(CurrentChar) then begin
  +   result:=result or sfEmptyWordBoundary;
  +  end;
  + end;
  + if (result and sfEmptyWordBoundary)=0 then begin
  +  result:=result or sfEmptyNonWordBoundary;
  + end;
  +end;
  +
  +function TFLREThreadLocalState.DFACacheState(const State:PFLREDFAState):PFLREDFAState; {$ifdef caninline}inline;{$endif}
  +begin
  +
  + // Is it already cached?
  + result:=DFAStateCache[State];
  + if not assigned(result) then begin
  +  // No, it is not already cached yet
  +
  +  // Do we need reset the states?
  +  if DFACountStatesCached>=MaxDFAStates then begin
  +   // Yes, so do it
  +   DFAReset;
  +  end;
  +
  +  // Move state in an own new memory instance
  +  result:=DFATakeOverState(State);
  +
  +  // Add state to state cache hash map
  +  DFAStateCache.Add(result);
  +  inc(DFACountStatesCached);
  +
  + end;
  +
  +end;
  +
  +procedure TFLREThreadLocalState.DFAAddInstructionThread(const State:PFLREDFAState;Instruction:PFLREInstruction);
  +var StackPointer:longint;
  +    Stack:PPFLREInstructionsStatic;
  +begin
  + Stack:=@DFAStackInstructions[0];
  + StackPointer:=0;
  + Stack^[StackPointer]:=Instruction;
  + inc(StackPointer);
  + while StackPointer>0 do begin
  +  dec(StackPointer);
  +  Instruction:=Stack[StackPointer];
  +  while assigned(Instruction) and (InstructionGenerations[Instruction^.IndexAndOpcode shr 8]<>Generation) do begin
  +   InstructionGenerations[Instruction^.IndexAndOpcode shr 8]:=Generation;
  +   case Instruction^.IndexAndOpcode and $ff of
  +    opJMP:begin
  +     Instruction:=Instruction^.Next;
  +    end;
  +    opSAVE:begin
  +{    if Instruction^.Value=0 then begin
  +      State.Flags:=State.Flags or sfDFAMatchBegins;
  +     end;{}
  +     Instruction:=Instruction^.Next;
  +    end;
  +    opSPLIT:begin
  +     Stack^[StackPointer]:=Instruction^.OtherNext;
  +     inc(StackPointer);
  +     Instruction:=Instruction^.Next;
  +    end;
  +    else begin
  +     if State.CountInstructions>=length(State.Instructions) then begin
  +      SetLength(State.Instructions,(State.CountInstructions+1)*2);
  +     end;
  +     State.Instructions[State.CountInstructions]:=Instruction;
  +     inc(State.CountInstructions);
  +     case Instruction^.IndexAndOpcode and $ff of
  +      opMATCH:begin
  +       State.Flags:=State.Flags or sfDFAMatchWins;
  +      end;
  +     end;
  +     break;
  +    end;
  +   end;
  +  end;
  + end;
  +end;
  +                                           
  +function TFLREThreadLocalState.DFAProcessNextState(State:PFLREDFAState;const CurrentChar:ansichar;const Reversed:boolean):PFLREDFAState;
  +var Counter:longint;
  +    Instruction:PFLREInstruction;
  +begin
  +
  + // Process state instructions
  + inc(Generation);
  + DFANewState.CountInstructions:=0;
  + DFANewState.Flags:=(State^.Flags and sfDFAStart) shl sfDFANeedShift;
  + for Counter:=0 To State^.CountInstructions-1 do begin
  +  Instruction:=State^.Instructions[Counter];
  +  case Instruction^.IndexAndOpcode and $ff of
  +   opSINGLECHAR:begin
  +    if byte(ansichar(CurrentChar))=Instruction^.Value then begin
  +     DFAAddInstructionThread(@DFANewState,Instruction^.Next);
  +    end;
  +   end;
  +   opCHAR:begin
  +    if CurrentChar in PFLRECharClass(pointer(ptruint(Instruction^.Value)))^ then begin
  +     DFAAddInstructionThread(@DFANewState,Instruction^.Next);
  +    end;
  +   end;
  +   opANY:begin
  +    DFAAddInstructionThread(@DFANewState,Instruction^.Next);
  +   end;
  +   opMATCH:begin
  +    if not ((rfLONGEST in Instance.Flags) or Reversed) then begin
  +     // We can stop processing the instruction list queue here since we found a match (for the PCRE leftmost first valid match behaviour)
  +     break;
  +    end;
  +   end;
  +   else begin
  +    // Oops?! Invalid byte code instruction for the DFA processing context! So abort and fallback to NFA...
  +    result:=nil;
  +    exit;
  +   end;
  +  end;
  + end;
  +
  + // Dead state? If yes, ...
  + if DFANewState.CountInstructions=0 then begin
  +  // ... drop it and take the dead state as the next state
  +  result:=DFADeadState;
  + end else begin  
  +  // .. otherwise try caching it
  +  result:=DFACacheState(@DFANewState);
  + end;
  +
  + // Connect the last state to the new state with the current char
  + State.NextStates[Instance.ByteMap[byte(ansichar(CurrentChar))]]:=result;
  +end;
  +
  +procedure TFLREThreadLocalState.DFADestroyStatePool(StatePool:PFLREDFAStatePool);
  +var Pool,NextPool:PFLREDFAStatePool;
  +    State:PFLREDFAState;
  +begin
  + Pool:=StatePool;
  + while assigned(Pool) do begin
  +  NextPool:=Pool^.Next;
  +  State:=Pool^.States;
  +  while assigned(State) and (State<>Pool^.EndState) do begin
  +   DFAFreeState(State);
  +   inc(ptruint(State),DFAStateSize);
  +  end;
  +  FreeMem(Pool^.States);
  +  FreeMem(Pool);
  +  Pool:=NextPool;
  + end;
  +end;
  +
  +procedure TFLREThreadLocalState.DFAFreeUsedStatePool;
  +var Pool,NextPool:PFLREDFAStatePool;
  +    State:PFLREDFAState;
  +begin
  + Pool:=DFAStatePoolUsed;
  + DFAStatePoolUsed:=nil;
  + while assigned(Pool) do begin
  +  NextPool:=Pool^.Next;
  +  State:=Pool^.States;
  +  while assigned(State) and (State<>Pool^.EndState) do begin
  +   DFAFreeState(State);
  +   inc(ptruint(State),DFAStateSize);
  +  end;
  +  FillChar(Pool^.States^,DFAStatePoolSize,AnsiChar(#0));
  +  Pool^.Next:=DFAStatePoolFree;
  +  DFAStatePoolFree:=Pool;
  +  Pool:=NextPool;
  + end;
  +end;
  +
  +function TFLREThreadLocalState.DFAAllocateNewStatePool:PFLREDFAStatePool;
  +begin
  + if assigned(DFAStatePoolFree) then begin
  +  result:=DFAStatePoolFree;
  +  DFAStatePoolFree:=result^.Next;
  + end else begin
  +  GetMem(result,SizeOf(TFLREDFAStatePool));
  +  FillChar(result^,SizeOf(TFLREDFAStatePool),AnsiChar(#0));
  +  GetMem(result^.States,DFAStatePoolSizePowerOfTwo);
  +  FillChar(result^.States^,DFAStatePoolSize,AnsiChar(#0));
  +  result^.EndState:=pointer(ptruint(ptruint(result^.States)+ptruint(DFAStatePoolSize)));
  + end;
  + result^.Next:=DFAStatePoolUsed;
  + DFAStatePoolUsed:=result;
  + result^.NextState:=result^.States;
  +end;
  +
  +function TFLREThreadLocalState.DFAGetState:PFLREDFAState;
  +begin
  + if DFAStatePoolUsed^.NextState=DFAStatePoolUsed^.EndState then begin
  +  DFAAllocateNewStatePool;
  + end;
  + result:=DFAStatePoolUsed^.NextState;
  + inc(ptruint(DFAStatePoolUsed^.NextState),DFAStateSize);
  +end;
  +
  +function TFLREThreadLocalState.DFATakeOverState(TakeOverFrom:PFLREDFAState):PFLREDFAState;
  +begin
  + result:=DFAGetState;
  + result^.Instructions:=TakeOverFrom^.Instructions;
  + result^.CountInstructions:=TakeOverFrom^.CountInstructions;
  + result^.Flags:=TakeOverFrom^.Flags;
  + TakeOverFrom^.Instructions:=nil;
  + TakeOverFrom^.CountInstructions:=0;
  + TakeOverFrom^.Flags:=0;
  +end;
  +
  +procedure TFLREThreadLocalState.DFAFreeState(State:PFLREDFAState);
  +begin
  + if assigned(State) then begin
  +  SetLength(State^.Instructions,0);
  +  if assigned(DFAStatePoolUsed) and
  +     ((ptruint(ptruint(State)-ptruint(DFAStatePoolUsed^.States))<DFAStatePoolSize) and
  +      (pointer(ptruint(ptruint(DFAStatePoolUsed^.NextState)-ptruint(DFAStateSize)))=State)) then begin
  +   FillChar(State^,DFAStateSize,AnsiChar(#0));
  +   dec(ptruint(DFAStatePoolUsed^.NextState),DFAStateSize);
  +  end;
  + end;
  +end;
  +
  +procedure TFLREThreadLocalState.DFAReset;
  +var State:PFLREDFAState;
  +begin
  +
  + // Reset state pools
  + DFAFreeUsedStatePool;
  + DFAAllocateNewStatePool;
  +
  + // Reset state cache
  + DFAStateCache.Clear;
  + DFACountStatesCached:=0;
  +
  + // Reset and recaching start states
  + if assigned(DFAAnchoredStartState) then begin
  +  State:=DFAAnchoredStartState;
  +  FillChar(State^.NextStates,DFANextStatesSize,AnsiChar(#0));
  +  DFAStateCache.Add(State);
  +  inc(DFACountStatesCached);
  + end;
  + if assigned(DFAUnanchoredStartState) then begin
  +  State:=DFAUnanchoredStartState;
  +  FillChar(State^.NextStates,DFANextStatesSize,AnsiChar(#0));
  +  DFAStateCache.Add(State);
  +  inc(DFACountStatesCached);
  + end;
  + if assigned(DFAReversedStartState) then begin
  +  State:=DFAReversedStartState;
  +  FillChar(State^.NextStates,DFANextStatesSize,AnsiChar(#0));
  +  DFAStateCache.Add(State);
  +  inc(DFACountStatesCached);
  + end;
  + if assigned(DFADeadState) then begin
  +  State:=DFADeadState;
  +  FillChar(State^.NextStates,DFANextStatesSize,AnsiChar(#0));
  +  DFAStateCache.Add(State);
  +  inc(DFACountStatesCached);
  + end;
  +
  +end;
  +
  +constructor TFLRE.Create(const ARegularExpression:ansistring;const AFlags:TFLREFlags=[]);
  +begin
  + inherited Create;
  +
  + CountParens:=0;
  +
  + AnchoredRootNode:=nil;
  +
  + UnanchoredRootNode:=nil;
  +
  + Nodes:=TList.Create;
  +
  + ForwardInstructions:=nil;
  + CountForwardInstructions:=0;
  +
  + BackwardInstructions:=nil;
  + CountBackwardInstructions:=0;
  +
  + AnchoredStartInstruction:=nil;
  + UnanchoredStartInstruction:=nil;
  + ReversedStartInstruction:=nil;
  +
  + CharClasses:=nil;
  + CountCharClasses:=0;
  +
  + FreeSubMatches:=nil;
  +
  + AllSubMatches:=TList.Create;
  +
  + RegularExpression:=ARegularExpression;
  +
  + Flags:=AFlags;
  +
  + FixedString:='';
  + FixedStringBoyerMooreNext:=nil;
  +
  + OnePassNFANodes:=nil;
  + OnePassNFANodesCount:=0;
  + OnePassNFAStart:=nil;
  + OnePassNFAStateSize:=0;
  + OnePassNFAWorkCaptures:=nil;
  + OnePassNFAMatchCaptures:=nil;
  + OnePassNFACharClassActions:=nil;
  + OnePassNFAReady:=false;
  +
  + BitStateNFACountVisited:=0;
  + BitStateNFAJobs:=nil;
  + BitStateNFACountJobs:=0;
  + BitStateNFAMaxJob:=0;
  + BitStateNFAWorkCaptures:=nil;
  + BitStateNFAMatchCaptures:=nil;
  + BitStateNFAReady:=false;
  +
  + DFANeedVerification:=false;
  +
  + BeginningJump:=false;
  + BeginningSplit:=false;
  + BeginningWildCard:=false;
  + BeginningAnchor:=false;
  +
  + NamedGroupStringList:=TStringList.Create;
  + NamedGroupStringIntegerPairHashMap:=TFLREStringIntegerPairHashMap.Create;
  +
  + ThreadLocalStateCriticalSection:=TCriticalSection.Create;
  +
  + ThreadLocalStates:=nil;
  + FreeThreadLocalStates:=nil;
  +
  + try
  +
  +  try
  +
  +   Parse;
  +
  +   Compile;
  +
  +  finally
  +   SetLength(CharClasses,CountCharClasses);
  +  end;
  +
  +  CountSubMatches:=(CountParens+1)*2;
  +
  +  CompilePrefix;
  +
  +  CompileFixedStringSearch;
  +
  +  CompilePrefixCharClasses;
  +
  +  CompileByteMapForOnePassNFAAndDFA;
  +
  +  CompileOnePassNFA;
  +
  +  if OnePassNFAReady then begin
  +   SetLength(OnePassNFAWorkCaptures,CountParens*2);
  +   SetLength(OnePassNFAMatchCaptures,CountParens*2);
  +  end;
  +
  +  BitStateNFAReady:=(CountForwardInstructions>0) and (CountForwardInstructions<512);
  +  if BitStateNFAReady then begin
  +   SetLength(BitStateNFAWorkCaptures,CountParens*2);
  +   SetLength(BitStateNFAMatchCaptures,CountParens*2);
  +  end;
  +
  +  BeginningWildcardLoop:=BeginningJump and BeginningSplit and BeginningWildcard;
  +  if rfLAZY in Flags then begin
  +   DoUnanchoredStart:=false;
  +  end else if rfGREEDY in Flags then begin
  +   DoUnanchoredStart:=not BeginningAnchor;
  +  end else begin
  +   DoUnanchoredStart:=(FixedStringLength=0) and (CountObviousPrefixCharClasses<CountPrefixCharClasses) and not BeginningAnchor;
  +  end;
  +
  + finally
  + end;
  +
  +end;
  +
  +destructor TFLRE.Destroy;
  +var Index:longint;
  +    SubMatches:PFLRESubMatches;
  +    NextCharClassAction:PFLREOnePassNFAStateCharClassAction;
  +    Flags:longword;
  +    ThreadLocalState,NextThreadLocalState:TFLREThreadLocalState;
  +begin
  +
  + ThreadLocalState:=ThreadLocalStates;
  + ThreadLocalStates:=nil;
  + while assigned(ThreadLocalState) do begin
  +  NextThreadLocalState:=ThreadLocalState.AllNext;
  +  ThreadLocalState.Free;
  +  ThreadLocalState:=NextThreadLocalState;
  + end;
  +
  + for Index:=0 to Nodes.Count-1 do begin
  +  FreeMem(Nodes[Index]);
  + end;
  + FreeAndNil(Nodes);
  +
  + SetLength(ForwardInstructions,0);
  +
  + SetLength(BackwardInstructions,0);
  +
  + for Index:=0 to CountCharClasses-1 do begin
  +  FreeMem(CharClasses[Index]);
  + end;
  + SetLength(CharClasses,0);
  + CountCharClasses:=0;
  +
  + while assigned(FreeSubMatches) do begin
  +  SubMatches:=FreeSubMatches;
  +  FreeSubMatches:=FreeSubMatches^.Next;
  +  SetLength(SubMatches^.SubMatches,0);
  +  Finalize(SubMatches^);
  +  FreeMem(SubMatches);
  + end;
  + FreeSubMatches:=nil;
  +
  + FreeAndNil(AllSubMatches);
  +
  + if assigned(OnePassNFANodes) then begin
  +  FreeMem(OnePassNFANodes);
  +  OnePassNFANodes:=nil;
  + end;
  + OnePassNFANodesCount:=0;
  + OnePassNFAStart:=nil;
  + OnePassNFAStateSize:=0;
  + SetLength(OnePassNFAWorkCaptures,0);
  + SetLength(OnePassNFAMatchCaptures,0);
  +
  + while assigned(OnePassNFACharClassActions) do begin
  +  NextCharClassAction:=OnePassNFACharClassActions^.AllNext;
  +  FreeMem(OnePassNFACharClassActions);
  +  OnePassNFACharClassActions:=NextCharClassAction;
  + end;
  + OnePassNFACharClassActions:=nil;
  +
  + SetLength(BitStateNFAJobs,0);
  + SetLength(BitStateNFAWorkCaptures,0);
  + SetLength(BitStateNFAMatchCaptures,0);
  +
  + SetLength(FixedStringBoyerMooreNext,0);
   
    NamedGroupStringList.Free;
    NamedGroupStringIntegerPairHashMap.Free;
  
positive.code:    end;
    end;
   end;
  end;
  
  function TFLRE.DFACacheState(const State:PFLREDFAState):PFLREDFAState; {$ifdef caninline}inline;{$endif}
  begin
  
   // Is it already cached?
   result:=DFAStateCache[State];
   if not assigned(result) then begin
    // No, it is not already cached yet
  
    // Do we need reset the states?
    if DFACountStatesCached>=MaxDFAStates then begin
     // Yes, so do it
     DFAReset;
    end;
  
    // Move state in an own new memory instance
    result:=DFATakeOverState(State);
  
    // Add state to state cache hash map
    DFAStateCache.Add(result);
    inc(DFACountStatesCached);
  
   end;
  
  end;
  
  procedure TFLRE.DFAAddInstructionThread(const State:PFLREDFAState;Instruction:PFLREInstruction);
  var StackPointer:longint;
      Stack:PPFLREInstructionsStatic;
  begin
   Stack:=@DFAStackInstructions[0];
   StackPointer:=0;
   Stack^[StackPointer]:=Instruction;
   inc(StackPointer);
   while StackPointer>0 do begin
    dec(StackPointer);
    Instruction:=Stack[StackPointer];
    while assigned(Instruction) and (Instruction^.Generation<>Generation) do begin
     Instruction^.Generation:=Generation;
     case Instruction^.IndexAndOpcode and $ff of
      opJMP:begin
       Instruction:=Instruction^.Next;
      end;
      opSAVE:begin
  {    if Instruction^.Value=0 then begin
        State.Flags:=State.Flags or sfDFAMatchBegins;
       end;{}
       Instruction:=Instruction^.Next;
      end;
      opSPLIT:begin
       Stack^[StackPointer]:=Instruction^.OtherNext;
       inc(StackPointer);
       Instruction:=Instruction^.Next;
      end;
      else begin
       if State.CountInstructions>=length(State.Instructions) then begin
        SetLength(State.Instructions,(State.CountInstructions+1)*2);
       end;
       State.Instructions[State.CountInstructions]:=Instruction;
       inc(State.CountInstructions);
       case Instruction^.IndexAndOpcode and $ff of
        opMATCH:begin
         State.Flags:=State.Flags or sfDFAMatchWins;
        end;
       end;
       break;
      end;
     end;
    end;
   end;
  end;
                                             
  function TFLRE.DFAProcessNextState(State:PFLREDFAState;const CurrentChar:ansichar;const Reversed:boolean):PFLREDFAState;
  var Counter:longint;
      Instruction:PFLREInstruction;
  begin
  
   // Process state instructions
   inc(Generation);
   DFANewState.CountInstructions:=0;
   DFANewState.Flags:=(State^.Flags and sfDFAStart) shl sfDFANeedShift;
   for Counter:=0 To State^.CountInstructions-1 do begin
    Instruction:=State^.Instructions[Counter];
    case Instruction^.IndexAndOpcode and $ff of
     opSINGLECHAR:begin
      if byte(ansichar(CurrentChar))=Instruction^.Value then begin
       DFAAddInstructionThread(@DFANewState,Instruction^.Next);
      end;
     end;
     opCHAR:begin
      if CurrentChar in PFLRECharClass(pointer(ptruint(Instruction^.Value)))^ then begin
       DFAAddInstructionThread(@DFANewState,Instruction^.Next);
      end;
     end;
     opANY:begin
      DFAAddInstructionThread(@DFANewState,Instruction^.Next);
     end;
     opMATCH:begin
      if not ((rfLONGEST in Flags) or Reversed) then begin
       // We can stop processing the instruction list queue here since we found a match (for the PCRE leftmost first valid match behaviour)
       break;
      end;
     end;
     else begin
      // Oops?! Invalid byte code instruction for the DFA processing context! So abort and fallback to NFA...
      result:=nil;
      exit;
     end;
    end;
   end;
  
   // Dead state? If yes, ...
   if DFANewState.CountInstructions=0 then begin
    // ... drop it and take the dead state as the next state
    result:=DFADeadState;
   end else begin  
    // .. otherwise try caching it
    result:=DFACacheState(@DFANewState);
   end;
  
   // Connect the last state to the new state with the current char
   State.NextStates[ByteMap[byte(ansichar(CurrentChar))]]:=result;
  end;
  
  procedure TFLRE.DFADestroyStatePool(StatePool:PFLREDFAStatePool);
  var Pool,NextPool:PFLREDFAStatePool;
      State:PFLREDFAState;
  begin
   Pool:=StatePool;
   while assigned(Pool) do begin
    NextPool:=Pool^.Next;
    State:=Pool^.States;
    while assigned(State) and (State<>Pool^.EndState) do begin
     DFAFreeState(State);
     inc(ptruint(State),DFAStateSize);
    end;
    FreeMem(Pool^.States);
    FreeMem(Pool);
    Pool:=NextPool;
   end;
  end;
  
  procedure TFLRE.DFAFreeUsedStatePool;
  var Pool,NextPool:PFLREDFAStatePool;
      State:PFLREDFAState;
  begin
   Pool:=DFAStatePoolUsed;
   DFAStatePoolUsed:=nil;
   while assigned(Pool) do begin
    NextPool:=Pool^.Next;
    State:=Pool^.States;
    while assigned(State) and (State<>Pool^.EndState) do begin
     DFAFreeState(State);
     inc(ptruint(State),DFAStateSize);
    end;
    FillChar(Pool^.States^,DFAStatePoolSize,AnsiChar(#0));
    Pool^.Next:=DFAStatePoolFree;
    DFAStatePoolFree:=Pool;
    Pool:=NextPool;
   end;
  end;
  
  function TFLRE.DFAAllocateNewStatePool:PFLREDFAStatePool;
  begin
   if assigned(DFAStatePoolFree) then begin
    result:=DFAStatePoolFree;
    DFAStatePoolFree:=result^.Next;
   end else begin
    GetMem(result,SizeOf(TFLREDFAStatePool));
    FillChar(result^,SizeOf(TFLREDFAStatePool),AnsiChar(#0));
    GetMem(result^.States,DFAStatePoolSizePowerOfTwo);
    FillChar(result^.States^,DFAStatePoolSize,AnsiChar(#0));
    result^.EndState:=pointer(ptruint(ptruint(result^.States)+ptruint(DFAStatePoolSize)));
   end;
   result^.Next:=DFAStatePoolUsed;
   DFAStatePoolUsed:=result;
   result^.NextState:=result^.States;
  end;
  
  function TFLRE.DFAGetState:PFLREDFAState;
  begin
   if DFAStatePoolUsed^.NextState=DFAStatePoolUsed^.EndState then begin
    DFAAllocateNewStatePool;
   end;
   result:=DFAStatePoolUsed^.NextState;
   inc(ptruint(DFAStatePoolUsed^.NextState),DFAStateSize);
  end;
  
  function TFLRE.DFATakeOverState(TakeOverFrom:PFLREDFAState):PFLREDFAState;
  begin
   result:=DFAGetState;
   result^.Instructions:=TakeOverFrom^.Instructions;
   result^.CountInstructions:=TakeOverFrom^.CountInstructions;
   result^.Flags:=TakeOverFrom^.Flags;
   TakeOverFrom^.Instructions:=nil;
   TakeOverFrom^.CountInstructions:=0;
   TakeOverFrom^.Flags:=0;
  end;
  
  procedure TFLRE.DFAFreeState(State:PFLREDFAState);
  begin
   if assigned(State) then begin
    SetLength(State^.Instructions,0);
    if assigned(DFAStatePoolUsed) and
       ((ptruint(ptruint(State)-ptruint(DFAStatePoolUsed^.States))<DFAStatePoolSize) and
        (pointer(ptruint(ptruint(DFAStatePoolUsed^.NextState)-ptruint(DFAStateSize)))=State)) then begin
     FillChar(State^,DFAStateSize,AnsiChar(#0));
     dec(ptruint(DFAStatePoolUsed^.NextState),DFAStateSize);
    end;
   end;
  end;
  
  procedure TFLRE.DFAReset;
  var State:PFLREDFAState;
  begin
  
   // Reset state pools
   DFAFreeUsedStatePool;
   DFAAllocateNewStatePool;
  
   // Reset state cache
   DFAStateCache.Clear;
   DFACountStatesCached:=0;
  
   // Reset and recaching start states
   if assigned(DFAAnchoredStartState) then begin
    State:=DFAAnchoredStartState;
    FillChar(State^.NextStates,DFANextStatesSize,AnsiChar(#0));
    DFAStateCache.Add(State);
    inc(DFACountStatesCached);
   end;
   if assigned(DFAUnanchoredStartState) then begin
    State:=DFAUnanchoredStartState;
    FillChar(State^.NextStates,DFANextStatesSize,AnsiChar(#0));
    DFAStateCache.Add(State);
    inc(DFACountStatesCached);
   end;
   if assigned(DFAReversedStartState) then begin
    State:=DFAReversedStartState;
    FillChar(State^.NextStates,DFANextStatesSize,AnsiChar(#0));
    DFAStateCache.Add(State);
    inc(DFACountStatesCached);
   end;
   if assigned(DFADeadState) then begin
    State:=DFADeadState;
    FillChar(State^.NextStates,DFANextStatesSize,AnsiChar(#0));
    DFAStateCache.Add(State);
    inc(DFACountStatesCached);
   end;
  
  end;
  
  function TFLRE.SearchMatchParallelNFA(const ThreadLocalState:TFLREThreadLocalState;var Captures:TFLRECaptures;const StartPosition,UntilExcludingPosition:longint;const UnanchoredStart:boolean):boolean;
  
negative.code: end;
  
  constructor TFLREThreadLocalState.Create(AInstance:TFLRE);
  var Index:longint;
      FLREDFAStateCreateTempDFAState:TFLREDFAState;
  begin
   inherited Create;
  
   AllNext:=nil;
   FreeNext:=nil;
  
   Instance:=AInstance;
  
   Input:=nil;
   InputLength:=0;
  
   Generation:=0;
  
   InstructionGenerations:=nil;
   SetLength(InstructionGenerations,AInstance.CountForwardInstructions+1);
   for Index:=0 to length(InstructionGenerations)-1 do begin
    InstructionGenerations[Index]:=-1;
   end;
  
   ThreadLists[0].Threads:=nil;
   ThreadLists[1].Threads:=nil;
   SetLength(ThreadLists[0].Threads,(AInstance.CountForwardInstructions+1)*4);
   SetLength(ThreadLists[1].Threads,(AInstance.CountForwardInstructions+1)*4);
  
   DFAStackInstructions:=nil;
   DFAStateCache:=TFLREDFAStateHashMap.Create;
  