anchor.diff:     end;
     end;
    end;
  + function NewUnicodeChar(UnicodeChar:longword):PFLRENode;
  + var Index:longint;
  +     TemporaryString:ansistring;
  +     TemporaryNode:PFLRENode;
  + begin
  +  result:=nil;
  +  TemporaryString:=UTF32CharToUTF8(UnicodeChar);
  +  try
  +   for Index:=1 to length(TemporaryString) do begin
  +    TemporaryNode:=NewNode(ntCHAR,nil,nil,nil,0);
  +    TemporaryNode^.CharClass:=[TemporaryString[Index]];
  +    if assigned(result) then begin
  +     result:=Concat(result,TemporaryNode);
  +    end else begin
  +     result:=TemporaryNode;
  +    end;
  +   end;
  +  finally
  +   TemporaryString:='';
  +  end;
  + end;
  + function NewCharEx(UnicodeChar:longword):PFLRENode;
  + begin           
  +  if (rfUTF8 in Flags) and (UnicodeChar>=$80) then begin
  +   result:=NewUnicodeChar(UnicodeChar);
  +  end else if UnicodeChar<=$ff then begin
  +   result:=NewNode(ntCHAR,nil,nil,nil,0);
  +   result^.CharClass:=[ansichar(byte(UnicodeChar))];
  +  end else begin
  +   raise EFLRE.Create('Syntax error');
  +  end;
  + end;
  + function NewChar(UnicodeChar:longword):PFLRENode;
  + var LowerCaseUnicodeChar,UpperCaseUnicodeChar:longword;
  + begin
  +  LowerCaseUnicodeChar:=UnicodeToLower(UnicodeChar);
  +  UpperCaseUnicodeChar:=UnicodeToUpper(UnicodeChar);
  +  if (rfCASEINSENSITIVE in Flags) and (LowerCaseUnicodeChar<>UpperCaseUnicodeChar) then begin
  +   if (rfUTF8 in Flags) and ((LowerCaseUnicodeChar>=$80) or (UpperCaseUnicodeChar>=$80)) then begin
  +    result:=NewAlt(NewCharEx(LowerCaseUnicodeChar),NewCharEx(UpperCaseUnicodeChar));
  +   end else begin
  +    result:=NewNode(ntCHAR,nil,nil,nil,0);
  +    result^.CharClass:=[ansichar(byte(LowerCaseUnicodeChar)),ansichar(byte(UpperCaseUnicodeChar))];
  +   end;
  +  end else begin
  +   if (rfUTF8 in Flags) and (UnicodeChar>=$80) then begin
  +    result:=NewCharEx(UnicodeChar);
  +   end else begin
  +    result:=NewNode(ntCHAR,nil,nil,nil,0);
  +    result^.CharClass:=[ansichar(byte(UnicodeChar))];
  +   end;
  +  end;
  + end;
  + function CompileUTF8Range(Lo,Hi:longword):PFLRENode;
  + type TString6Chars=string[6];
  + const Seq0010ffff:array[0..6,0..4,0..1] of longint=((($00,$7f),(-1,-1),(-1,-1),(-1,-1),(-1,-1)),        // 00-7F
  +                                                     (($c2,$df),($80,$bf),(-1,-1),(-1,-1),(-1,-1)),      // C2-DF 80-BF
  +                                                     (($e0,$e0),($a0,$bf),($80,$bf),(-1,-1),(-1,-1)),    // E0-E0 A0-BF 80-BF
  +                                                     (($e1,$ef),($80,$bf),($80,$bf),(-1,-1),(-1,-1)),    // E1-EF 80-BF 80-BF
  +                                                     (($f0,$f0),($80,$bf),($80,$bf),($80,$bf),(-1,-1)),  // F0-F0 90-BF 80-BF 80-BF
  +                                                     (($f1,$f3),($80,$bf),($80,$bf),($80,$bf),(-1,-1)),  // F1-F3 80-BF 80-BF 80-BF
  +                                                     (($f4,$f4),($80,$bf),($80,$bf),($80,$bf),(-1,-1))); // F4-F4 80-8F 80-BF 80-BF
  +       HexChars:array[$0..$f] of ansichar='0123456789ABCDEF';
  + var OutputNode,NodeChain:PFLRENode;
  +  procedure Add(const NewNode:PFLRENode);
  +  begin
  +   if assigned(NewNode) then begin
  +    if assigned(NodeChain) then begin
  +     NodeChain:=Concat(OutputNode,NewNode);
  +    end else begin
  +     NodeChain:=NewNode;
  +    end;
  +   end;
  +  end;
  +  procedure AddSuffix;
  +  begin
  +   if assigned(NodeChain) then begin
  +    if assigned(OutputNode) then begin
  +     OutputNode:=NewAlt(OutputNode,NodeChain);
  +    end else begin
  +     OutputNode:=NodeChain;
  +    end;
  +    NodeChain:=nil;
  +   end;
  +  end;
  +  function ToString(CharValue:longword):TString6Chars;
  +  begin
  +   case CharValue of
  +    $00000000..$0000007f:begin
  +     SetLength(result,1);
  +     result[1]:=ansichar(byte(CharValue));
  +    end;
  +    $00000080..$000007ff:begin
  +     SetLength(result,2);
  +     result[1]:=ansichar(byte($c0 or ((CharValue shr 6) and $1f)));
  +     result[2]:=ansichar(byte($80 or (CharValue and $3f)));
  +    end;
  + // {$ifdef PLREStrictUTF8}$00000800..$0000d7ff,$0000e000..$0000ffff{$else}$00000800..$0000ffff{$endif}:begin
  +    $00000800..$0000ffff:begin
  +     SetLength(result,3);
  +     result[1]:=ansichar(byte($e0 or ((CharValue shr 12) and $0f)));
  +     result[2]:=ansichar(byte($80 or ((CharValue shr 6) and $3f)));
  +     result[3]:=ansichar(byte($80 or (CharValue and $3f)));
  +    end;
  +    $00010000..$0010ffff:begin
  +     SetLength(result,4);
  +     result[1]:=ansichar(byte($f0 or ((CharValue shr 18) and $07)));
  +     result[2]:=ansichar(byte($80 or ((CharValue shr 12) and $3f)));
  +     result[3]:=ansichar(byte($80 or ((CharValue shr 6) and $3f)));
  +     result[4]:=ansichar(byte($80 or (CharValue and $3f)));
  +    end;
  +    $00200000..$03ffffff:begin
  +     SetLength(result,5);
  +     result[1]:=ansichar(byte($f8 or ((CharValue shr 24) and $03)));
  +     result[2]:=ansichar(byte($80 or ((CharValue shr 18) and $3f)));
  +     result[3]:=ansichar(byte($80 or ((CharValue shr 12) and $3f)));
  +     result[4]:=ansichar(byte($80 or ((CharValue shr 6) and $3f)));
  +     result[5]:=ansichar(byte($80 or (CharValue and $3f)));
  +    end;
  +    $04000000..$7fffffff:begin
  +     SetLength(result,6);
  +     result[1]:=ansichar(byte($fc or ((CharValue shr 30) and $01)));
  +     result[2]:=ansichar(byte($80 or ((CharValue shr 24) and $3f)));
  +     result[3]:=ansichar(byte($80 or ((CharValue shr 18) and $3f)));
  +     result[4]:=ansichar(byte($80 or ((CharValue shr 12) and $3f)));
  +     result[5]:=ansichar(byte($80 or ((CharValue shr 6) and $3f)));
  +     result[6]:=ansichar(byte($80 or (CharValue and $3f)));
  +    end;
  +    else begin
  +     SetLength(result,3);
  +     result[1]:=#$ef;
  +     result[2]:=#$bf;
  +     result[3]:=#$bd;
  +    end;
  +   end;
  +  end;
  +  procedure AddRange(const Lo,Hi:byte);
  +  var Node:PFLRENode;
  +  begin
  +   Node:=NewNode(ntCHAR,nil,nil,nil,0);
  +   Node^.CharClass:=[ansichar(byte(Lo))..ansichar(byte(Hi))];
  +   Add(Node);
  +  end;
  +  procedure ProcessRange(Lo,Hi:longword);
  +  var i,m:longword;
  +      StrLo,StrHi:TString6Chars;
  +      CurrentNode:PFLRENode;
  +  begin
  +   if Hi>$0010ffff then begin
  +    Hi:=$0010ffff;
  +   end;
  +   if Lo<=Hi then begin
  +    if (Lo=$00000000) and (Hi=$0010ffff) then begin
  +     for m:=low(Seq0010ffff) to high(Seq0010ffff) do begin
  +      for i:=low(Seq0010ffff[m]) to high(Seq0010ffff[m]) do begin
  +       if Seq0010ffff[m,i,0]<0 then begin
  +        break;
  +       end;
  +       AddRange(byte(Seq0010ffff[m,i,0]),byte(Seq0010ffff[m,i,1]));
  +      end;
  +      AddSuffix;
  +     end;
  +    end else if (Lo=$00000080) and (Hi=$0010ffff) then begin
  +     for m:=1 to high(Seq0010ffff) do begin
  +      for i:=low(Seq0010ffff[m]) to high(Seq0010ffff[m]) do begin
  +       if Seq0010ffff[m,i,0]<0 then begin
  +        break;
  +       end;
  +       AddRange(byte(Seq0010ffff[m,i,0]),byte(Seq0010ffff[m,i,1]));
  +      end;
  +      AddSuffix;
  +     end;
  +    end else begin
  +     for i:=1 to 3 do begin
  +      if i=1 then begin
  +       m:=7;
  +      end else begin
  +       m:=(7-i)+(6*(i-1));
  +      end;
  +      m:=(1 shl m)-1;
  +      if (Lo<=m) and (m<Hi) then begin
  +       ProcessRange(Lo,m);
  +       ProcessRange(m+1,Hi);
  +       exit;
  +      end;
  +     end;
  +     if Hi<128 then begin
  +      AddRange(Lo,Hi);
  +      AddSuffix;
  +     end else begin
  +      for i:=1 to 3 do begin
  +       m:=(1 shl (6*i))-1;
  +       if (Lo and not m)<>(Hi and not m) then begin
  +        if (Lo and m)<>0 then begin
  +         ProcessRange(Lo,Lo or m);
  +         ProcessRange((Lo or m)+1,Hi);
  +         exit;
  +        end else if (Hi and m)<>m then begin
  +         ProcessRange(Lo,(Hi and not m)-1);
  +         ProcessRange(Hi and not m,Hi);
  +         exit;
  +        end;
  +       end;
  +      end;
  +      StrLo:=ToString(Lo);
  +      StrHi:=ToString(Hi);
  +      if length(StrLo)=length(StrHi) then begin
  +       for i:=1 to length(StrLo) do begin
  +        AddRange(byte(StrLo[i]),byte(StrHi[i]));
  +       end;
  +       AddSuffix;
  +      end;
  +     end;
  +    end;
  +   end;
  +  end;
  + begin
  +  OutputNode:=nil;
  +  NodeChain:=nil;
  +  ProcessRange(Lo,Hi);
  +  result:=OutputNode;
  + end;
  + function NewUnicodeCharClass(UnicodeCharClass:TFLREUnicodeCharClass):PFLRENode;
  + var Range:TFLREUnicodeCharClassRange;
  +     Node:PFLRENode;
  + begin
  +  UnicodeCharClass.Optimize;
  +  if UnicodeCharClass.IsSingle then begin
  +   result:=NewChar(UnicodeCharClass.First.Lo);
  +  end else begin
  +   if (rfUTF8 in Flags) and assigned(UnicodeCharClass.Last) and (UnicodeCharClass.Last.Hi>=128) then begin
  +    result:=nil;
  +    Range:=UnicodeCharClass.First;
  +    while assigned(Range) do begin
  +     if (Range.Lo<=$10ffff) and (Range.Lo=Range.Hi) then begin
  +      Node:=NewCharEx(Range.Lo);
  +     end else begin
  +      Node:=CompileUTF8Range(Range.Lo,Range.Hi);
  +     end;
  +     if assigned(result) then begin
  +      result:=NewAlt(result,Node);
  +     end else begin
  +      result:=Node;
  +     end;
  +     Range:=Range.Next;
  +    end;
  +   end else begin
  +    result:=NewNode(ntCHAR,nil,nil,nil,0);
  +    result^.CharClass:=[];
  +    Range:=UnicodeCharClass.First;
  +    while assigned(Range) and (Range.Lo<256) do begin
  +     if Range.Lo=Range.Hi then begin
  +      Include(result^.CharClass,ansichar(byte(Range.Lo)));
  +     end else begin
  +      if Range.Hi<256 then begin
  +       result^.CharClass:=result^.CharClass+[ansichar(byte(Range.Lo))..ansichar(byte(Range.Hi))];
  +      end else begin
  +       result^.CharClass:=result^.CharClass+[ansichar(byte(Range.Lo))..#$ff];
  +      end;
  +     end;
  +     Range:=Range.Next;
  +    end;
  +   end;
  +  end;
  + end;
  + function TestClassPOSIXCharacterClass:boolean;
  + var LocalSourcePosition,i:longint;
  + begin
  +  result:=false;
  +  LocalSourcePosition:=SourcePosition;
  +
  +  if (LocalSourcePosition<=SourceLength) and (Source[LocalSourcePosition]='[') then begin
  +   inc(LocalSourcePosition);
  +  end else begin
  +   exit;
  +  end;
  +
  +  if (LocalSourcePosition<=SourceLength) and (Source[LocalSourcePosition]=':') then begin
  +   inc(LocalSourcePosition);
  +  end else begin
  +   exit;
  +  end;
  +
  +  if (LocalSourcePosition<=SourceLength) and (Source[LocalSourcePosition]='^') then begin
  +   inc(LocalSourcePosition);
  +  end else begin
  +   exit;
  +  end;
  +
  +  i:=0;
  +  while (LocalSourcePosition<=SourceLength) and (Source[LocalSourcePosition] in ['a'..'z','A'..'Z','0'..'9','_','-']) do begin
  +   inc(LocalSourcePosition);
  +  end;
  +  if i=0 then begin
  +   exit;
  +  end;
  +
  +  if (LocalSourcePosition<=SourceLength) and (Source[LocalSourcePosition]=':') then begin
  +   inc(LocalSourcePosition);
  +  end else begin
  +   exit;
  +  end;
  +
  +  if (LocalSourcePosition<=SourceLength) and (Source[LocalSourcePosition]=']') then begin
  +   inc(LocalSourcePosition);
  +  end else begin
  +   exit;
  +  end;
  +
  +  result:=true;
  + end;
  + function ParseClassPOSIXCharacterClass(const UnicodeCharClass:TFLREUnicodeCharClass;const CanBeAlreadyCanonicalized:boolean):boolean;
  + var Name:ansistring;
  +     Negate,IgnoreCase:boolean;
  + begin
  +  result:=false;
  +
  +  IgnoreCase:=CanBeAlreadyCanonicalized and (rfCASEINSENSITIVE in Flags);
  +
  +  if (SourcePosition<=SourceLength) and (Source[SourcePosition]='[') then begin
  +   inc(SourcePosition);
  +  end else begin
  +   raise EFLRE.Create('Syntax error');
  +  end;
  +
  +  if (SourcePosition<=SourceLength) and (Source[SourcePosition]=':') then begin
  +   inc(SourcePosition);
  +  end else begin
  +   raise EFLRE.Create('Syntax error');
  +  end;
  +
  +  if (SourcePosition<=SourceLength) and (Source[SourcePosition]='^') then begin
  +   inc(SourcePosition);
  +   Negate:=true;
  +  end else begin
  +   Negate:=false;
  +  end;
  +
  +  Name:='';
  +  while (SourcePosition<=SourceLength) and (Source[SourcePosition] in ['a'..'z','A'..'Z','0'..'9','_','-']) do begin
  +   Name:=Name+Source[SourcePosition];
  +   inc(SourcePosition);
  +  end;
  +
  +  if (SourcePosition<=SourceLength) and (Source[SourcePosition]=':') then begin
  +   inc(SourcePosition);
  +  end else begin
  +   raise EFLRE.Create('Syntax error');
  +  end;
  +
  +  if (SourcePosition<=SourceLength) and (Source[SourcePosition]=']') then begin
  +   inc(SourcePosition);
  +  end else begin
  +   raise EFLRE.Create('Syntax error');
  +  end;
  +
  +  GetCharClassPerName(Name,UnicodeCharClass,IgnoreCase);
  +  if Negate then begin
  +   UnicodeCharClass.Invert;
  +   UnicodeCharClass.Inverted:=false;
  +  end;
  +
  +  result:=true;
  + end;
  + function ParseClassEscapeUnicodeProperty(const UnicodeCharClass:TFLREUnicodeCharClass;const CanBeAlreadyCanonicalized:boolean):boolean;
  + var Identifier:ansistring;
  +     i:longword;
  +     IgnoreCase,IsNegative:boolean;
  +     f,LastSourcePos,UntilSourcePos:longint;
  + begin
  +  result:=false;
  +  if SourcePosition<=SourceLength then begin
  +   IgnoreCase:=CanBeAlreadyCanonicalized and (rfCASEINSENSITIVE in Flags);
  +   case Source[SourcePosition] of
  +    'a'..'z','A'..'Z':begin
  +     f:=UnicodeClassHashMap.GetValue(UTF32CharToUTF8(UnicodeToLower(byte(ansichar(Source[SourcePosition])))));
  +     if f>=0 then begin
  +      inc(SourcePosition);
  +      UnicodeCharClass.AddUnicodeCategory(f,IgnoreCase);
  +      result:=true;
  +     end;
  +    end;
  +    '{':begin
  +     LastSourcePos:=SourcePosition;
  +     inc(SourcePosition);
  +     if (SourcePosition<=SourceLength) and (Source[SourcePosition]='^') then begin
  +      LastSourcePos:=SourcePosition;
  +      inc(SourcePosition);
  +      IsNegative:=true;
  +      IgnoreCase:=false;
  +     end else begin
  +      IsNegative:=false;
  +     end;
  +     UntilSourcePos:=LastSourcePos;
  +     while (SourcePosition<=SourceLength) and (Source[SourcePosition] in ['a'..'z','A'..'Z','0'..'9','_','-']) do begin
  +      UntilSourcePos:=SourcePosition;
  +      inc(SourcePosition);
  +     end;
  +     if (LastSourcePos<UntilSourcePos) and ((SourcePosition<=SourceLength) and (Source[SourcePosition]='}')) then begin
  +      Identifier:=UTF8LowerCase(copy(Source,LastSourcePos,UntilSourcePos-LastSourcePos));
  +      inc(SourcePosition);
  +      GetCharClassPerName(Identifier,UnicodeCharClass,IgnoreCase);
  +      if IsNegative and assigned(UnicodeCharClass.First) then begin
  +       UnicodeCharClass.Invert;
  +       UnicodeCharClass.Inverted:=false;
  +       if CanBeAlreadyCanonicalized and (rfCASEINSENSITIVE in Flags) then begin
  +        UnicodeCharClass.Canonicalize;
  +       end;
  +      end;
  +      result:=true;
  +     end;
  +    end;
  +   end;
  +  end;
  + end;
  + function ParseClassEscape(const CanBeAlreadyCanonicalized:boolean):TFLREUnicodeCharClass;
  + var i:longint;
  +     IgnoreCase:boolean;
  +     UnicodeChar:longword;
  + begin
  +  result:=nil;
  +  try
  +   IgnoreCase:=CanBeAlreadyCanonicalized and (rfCASEINSENSITIVE in Flags);
  +   result:=TFLREUnicodeCharClass.Create(self);
  +   if (SourcePosition<=SourceLength) and (Source[SourcePosition] in ['0'..'9']) then begin
  +    i:=0;
  +    while (SourcePosition<=SourceLength) and (Source[SourcePosition] in ['0'..'9']) do begin
  +     i:=(i*10)+longint(byte(ansichar(Source[SourcePosition]))-byte(ansichar('0')));
  +     inc(SourcePosition);
  +    end;
  +    if i<>0 then begin
  +     raise EFLRE.Create('Syntax error');
  +    end;
  +    result.AddChar(i,IgnoreCase);
  +    result.Canonicalized:=IgnoreCase;
  +    exit;
  +   end;
  +   case Source[SourcePosition] of
  +    'a':begin
  +     inc(SourcePosition);
  +     result.AddChar($0007,IgnoreCase);
  +     result.Canonicalized:=true;
  +    end;
  +    'b':begin
  +     inc(SourcePosition);
  +     result.AddChar($0008,IgnoreCase);
  +     result.Canonicalized:=true;
  +    end;
  +    'B':begin
  +     inc(SourcePosition);
  +     result.AddChar(ord('\'),IgnoreCase);
  +     result.Canonicalized:=true;
  +    end;
  +    't':begin
  +     inc(SourcePosition);
  +     result.AddChar(9,IgnoreCase);
  +     result.Canonicalized:=true;
  +    end;
  +    'n':begin
  +     inc(SourcePosition);
  +     result.AddChar(10,IgnoreCase);
  +     result.Canonicalized:=true;
  +    end;
  +    'v':begin
  +     inc(SourcePosition);
  +     result.AddChar(11,IgnoreCase);
  +     result.Canonicalized:=true;
  +    end;
  +    'f':begin
  +     inc(SourcePosition);
  +     result.AddChar(12,IgnoreCase);
  +     result.Canonicalized:=true;
  +    end;
  +    'r':begin
  +     inc(SourcePosition);
  +     result.AddChar(13,IgnoreCase);
  +     result.Canonicalized:=true;
  +    end;
  +    'e':begin
  +     inc(SourcePosition);
  +     result.AddChar($1b,IgnoreCase);
  +     result.Canonicalized:=true;
  +    end;
  +    'w','W':begin
  +     if rfUTF8 in Flags then begin
  +      for i:=0 to length(UnicodeCharRangeClasses[ucrWORDS])-1 do begin
  +       result.AddRange(UnicodeCharRangeClasses[ucrWORDS,i,0],UnicodeCharRangeClasses[ucrWORDS,i,1],IgnoreCase);
  +      end;
  +     end else begin
  +      result.AddRange(ord('a'),ord('z'),IgnoreCase);
  +      result.AddRange(ord('A'),ord('Z'),IgnoreCase);
  +      result.AddRange(ord('0'),ord('9'),IgnoreCase);
  +      result.AddChar(ord('_'),IgnoreCase);
  +     end;
  +     if Source[SourcePosition]='W' then begin
  +      result.Invert;
  +      result.Inverted:=false;
  +     end;
  +     result.Canonicalized:=true;
  +     inc(SourcePosition);
  +    end;
  +    's','S':begin
  +     if rfUTF8 in Flags then begin
  +      for i:=0 to length(UnicodeCharRangeClasses[ucrWHITESPACES])-1 do begin
  +       result.AddRange(UnicodeCharRangeClasses[ucrWHITESPACES,i,0],UnicodeCharRangeClasses[ucrWHITESPACES,i,1],IgnoreCase);
  +      end;
  +     end else begin
  +      result.AddRange(9,13,IgnoreCase);
  +      result.AddChar(32,IgnoreCase);
  +     end;
  +     if Source[SourcePosition]='S' then begin
  +      result.Invert;
  +      result.Inverted:=false;
  +     end;
  +     result.Canonicalized:=true;
  +     inc(SourcePosition);
  +    end;
  +    'd','D':begin
  +     if rfUTF8 in Flags then begin
  +      for i:=0 to length(UnicodeCharRangeClasses[ucrDIGITS])-1 do begin
  +       result.AddRange(UnicodeCharRangeClasses[ucrDIGITS,i,0],UnicodeCharRangeClasses[ucrDIGITS,i,1],IgnoreCase);
  +      end;
  +     end else begin
  +      result.AddRange(ord('0'),ord('9'),IgnoreCase);
  +     end;
  +     if Source[SourcePosition]='D' then begin
  +      result.Invert;
  +      result.Inverted:=false;
  +     end;
  +     result.Canonicalized:=true;
  +     inc(SourcePosition);
  +    end;
  +    'p':begin
  +     inc(SourcePosition);
  +     if ParseClassEscapeUnicodeProperty(result,CanBeAlreadyCanonicalized) then begin
  +      result.Canonicalized:=true;
  +     end else begin
  +      raise EFLRE.Create('Syntax error');
  +     end;
  +    end;
  +    'P':begin
  +     inc(SourcePosition);
  +     if ParseClassEscapeUnicodeProperty(result,CanBeAlreadyCanonicalized) then begin
  +      result.Canonicalized:=true;
  +     end else begin
  +      raise EFLRE.Create('Syntax error');
  +     end;
  +     result.Invert;
  +     result.Inverted:=false;
  +     result.Canonicalized:=true;
  +    end;
  +    'c':begin
  +     inc(SourcePosition);
  +     if (SourcePosition<=SourceLength) and (Source[SourcePosition] in ['a'..'z','A'..'Z']) then begin
  +      case Source[SourcePosition] of
  +       'a'..'z':begin
  +        result.AddChar(byte(ansichar(Source[SourcePosition]))-byte(ansichar('a')),IgnoreCase);
  +       end;
  +       'A'..'Z':begin
  +        result.AddChar(byte(ansichar(Source[SourcePosition]))-byte(ansichar('A')),IgnoreCase);
  +       end;
  +      end;
  +      result.Canonicalized:=IgnoreCase;
  +     end else begin
  +      raise EFLRE.Create('Syntax error');
  +     end;
  +    end;
  +    'x':begin
  +     inc(SourcePosition);
  +     if ((SourcePosition+1)<=SourceLength) and
  +        (Source[SourcePosition+0] in ['0'..'9','a'..'f','A'..'F']) and
  +        (Source[SourcePosition+1] in ['0'..'9','a'..'f','A'..'F']) then begin
  +      result.AddChar((Hex2Value(Source[SourcePosition+0]) shl 8) or Hex2Value(Source[SourcePosition+1]),IgnoreCase);
  +      inc(SourcePosition,2);
  +     end else if (SourcePosition<=SourceLength) and (Source[SourcePosition]='{') then begin
  +      inc(SourcePosition);
  +      UnicodeChar:=0;
  +      while (SourcePosition<=SourceLength) and (Source[SourcePosition] in ['0'..'9','a'..'f','A'..'F']) do begin
  +       UnicodeChar:=(UnicodeChar shl 4) or Hex2Value(Source[SourcePosition]);
  +       inc(SourcePosition);
  +      end;
  +      if (SourcePosition<=SourceLength) and (Source[SourcePosition]='}') then begin
  +       inc(SourcePosition);
  +       result.AddChar(UnicodeChar,IgnoreCase);
  +      end else begin
  +       raise EFLRE.Create('Syntax error');
  +      end;
  +     end else begin
  +      raise EFLRE.Create('Syntax error');
  +     end;
  +    end;
  +    'u':begin
  +     inc(SourcePosition);
  +     if ((SourcePosition+3)<=SourceLength) and
  +        (Source[SourcePosition+0] in ['0'..'9','a'..'f','A'..'F']) and
  +        (Source[SourcePosition+1] in ['0'..'9','a'..'f','A'..'F']) and
  +        (Source[SourcePosition+2] in ['0'..'9','a'..'f','A'..'F']) and
  +        (Source[SourcePosition+3] in ['0'..'9','a'..'f','A'..'F']) then begin
  +      UnicodeChar:=(Hex2Value(Source[SourcePosition+0]) shl 24) or (Hex2Value(Source[SourcePosition+1]) shl 16) or (Hex2Value(Source[SourcePosition+2]) shl 8) or Hex2Value(Source[SourcePosition+3]);
  +      inc(SourcePosition,4);
  +      result.AddChar(UnicodeChar,IgnoreCase);
  +     end else begin
  +      raise EFLRE.Create('Syntax error');
  +     end;
  +    end;
  +    'U':begin
  +     inc(SourcePosition);
  +     if (SourcePosition<=SourceLength) and (Source[SourcePosition] in ['0'..'9','a'..'f','A'..'F']) then begin
  +      UnicodeChar:=0;
  +      while (SourcePosition<=SourceLength) and (Source[SourcePosition] in ['0'..'9','a'..'f','A'..'F']) do begin
  +       UnicodeChar:=(UnicodeChar shl 4) or Hex2Value(Source[SourcePosition]);
  +       inc(SourcePosition);
  +      end;
  +      result.AddChar(UnicodeChar,IgnoreCase);
  +     end else begin
  +      raise EFLRE.Create('Syntax error');
  +     end;
  +    end;
  +    'Q':begin
  +     inc(SourcePosition);
  +     while SourcePosition<=SourceLength do begin
  +      if Source[SourcePosition]='\' then begin
  +       inc(SourcePosition);
  +       if (SourcePosition<=SourceLength) and (Source[SourcePosition]='E') then begin
  +        inc(SourcePosition);
  +        break;
  +       end else begin
  +        result.AddChar(ord('\'),IgnoreCase);
  +       end;
  +      end else begin
  +       if (rfUTF8 in Flags) and (byte(ansichar(Source[SourcePosition]))>=$80) then begin
  +        UnicodeChar:=UTF8CodeUnitGetCharAndIncFallback(Source,SourcePosition);
  +        result.AddChar(UnicodeChar,IgnoreCase);
  +       end else begin
  +        result.AddChar(byte(ansichar(Source[SourcePosition])),IgnoreCase);
  +        inc(SourcePosition);
  +       end;
  +      end;
  +     end;
  +     result.Canonicalized:=IgnoreCase;
  +    end;
  +    else begin
  +     if (rfUTF8 in Flags) and (byte(ansichar(Source[SourcePosition]))>=$80) then begin
  +      UnicodeChar:=UTF8CodeUnitGetCharAndIncFallback(Source,SourcePosition);
  +      result.AddChar(UnicodeChar,IgnoreCase);
  +     end else begin
  +      result.AddChar(byte(ansichar(Source[SourcePosition])),IgnoreCase);
  +      inc(SourcePosition);
  +     end;
  +    end;
  +   end;
  +  except
  +   FreeAndNil(result);
  +   raise;
  +  end;
  + end;
  + function ParseClassAtom:TFLREUnicodeCharClass;
  + begin
  +  result:=nil;
  +  try
  +   if SourcePosition<=SourceLength then begin
  +    if Source[SourcePosition]='\' then begin
  +     inc(SourcePosition);
  +     result:=ParseClassEscape(false);
  +    end else if TestClassPOSIXCharacterClass then begin
  +     result:=TFLREUnicodeCharClass.Create(self);
  +     if not ParseClassPOSIXCharacterClass(result,false) then begin
  +      raise EFLRE.Create('Syntax error');
  +     end;
  +    end else begin
  +     result:=TFLREUnicodeCharClass.Create(self);
  +     if (rfUTF8 in Flags) and (byte(ansichar(Source[SourcePosition]))>=$80) then begin
  +      result.AddChar(UTF8CodeUnitGetCharAndIncFallback(Source,SourcePosition));
  +     end else begin
  +      result.AddChar(byte(ansichar(Source[SourcePosition])));
  +      inc(SourcePosition);
  +     end;
  +    end;
  +   end else begin
  +    raise EFLRE.Create('Syntax error');
  +   end;
  +  except
  +   FreeAndNil(result);
  +   raise;
  +  end;
  + end;
  + function ParseCharacterClass:TFLREUnicodeCharClass;
  + var InvertFlag:boolean;
  +     a,b,c:TFLREUnicodeCharClass;
  + begin
  +  result:=nil;
  +  try
  +   a:=nil;
  +   b:=nil;
  +   try
  +    result:=TFLREUnicodeCharClass.Create(self);
  +    if (SourcePosition<=SourceLength) and (Source[SourcePosition]='[') then begin
  +     inc(SourcePosition);
  +    end else begin
  +     raise EFLRE.Create('Syntax error');
  +    end;
  +    if (SourcePosition<=SourceLength) and (Source[SourcePosition]='^') then begin
  +     inc(SourcePosition);
  +     InvertFlag:=true;
  +    end else begin
  +     InvertFlag:=false;
  +    end;
  +    while (SourcePosition<=SourceLength) and (Source[SourcePosition]<>']') do begin
  +     if ((SourcePosition+1)<=SourceLength) and ((Source[SourcePosition]='-') and (Source[SourcePosition+1] in ['[',']'])) then begin
  +      inc(SourcePosition);
  +      if Source[SourcePosition]=']' then begin
  +       a:=TFLREUnicodeCharClass.Create(self);
  +       a.AddChar(ord('-'));
  +      end else begin
  +       a:=ParseCharacterClass;
  +       b:=TFLREUnicodeCharClass.Create(self);
  +       if b.Subtraction(result,a) then begin
  +        FreeAndNil(result);
  +        result:=b;
  +        b:=nil;
  +       end else begin
  +        FreeAndNil(b);
  +       end;
  +       FreeAndNil(a);
  +       if not ((SourcePosition<=SourceLength) and (Source[SourcePosition]=']')) then begin
  +        raise EFLRE.Create('Syntax error');
  +       end;
  +       continue;
  +      end;
  +     end else begin
  +      a:=ParseClassAtom;
  +     end;
  +     if ((SourcePosition+1)<=SourceLength) and ((Source[SourcePosition]='&') and (Source[SourcePosition+1]='&')) then begin
  +      inc(SourcePosition,2);
  +      if (SourcePosition<=SourceLength) and (Source[SourcePosition] in ['[',']']) then begin
  +       if Source[SourcePosition]='[' then begin
  +        if assigned(a) then begin
  +         result.TakeoverCombine(a);
  +         FreeAndNil(a);
  +        end;
  +        a:=ParseCharacterClass;
  +        b:=TFLREUnicodeCharClass.Create(self);
  +        if b.Intersection(result,a) then begin
  +         FreeAndNil(result);
  +         result:=b;
  +         b:=nil;
  +        end else begin
  +         FreeAndNil(b);
  +        end;
  +        FreeAndNil(a);
  +        if not ((SourcePosition<=SourceLength) and (Source[SourcePosition]=']')) then begin
  +         raise EFLRE.Create('Syntax error');
  +        end;
  +        continue;
  +       end else begin
  +        raise EFLRE.Create('Syntax error');
  +       end;
  +      end else begin
  +       raise EFLRE.Create('Syntax error');
  +      end;
  +     end else if (SourcePosition<=SourceLength) and (Source[SourcePosition]='-') then begin
  +      inc(SourcePosition);
  +      if (SourcePosition<=SourceLength) and (Source[SourcePosition] in ['[',']']) then begin
  +       if Source[SourcePosition]='[' then begin
  +        if assigned(a) then begin
  +         result.TakeoverCombine(a);
  +         FreeAndNil(a);
  +        end;
  +        a:=ParseCharacterClass;
  +        b:=TFLREUnicodeCharClass.Create(self);
  +        if b.Subtraction(result,a) then begin
  +         FreeAndNil(result);
  +         result:=b;
  +         b:=nil;
  +        end else begin
  +         FreeAndNil(b);
  +        end;
  +        FreeAndNil(a);
  +        if not ((SourcePosition<=SourceLength) and (Source[SourcePosition]=']')) then begin
  +         raise EFLRE.Create('Syntax error');
  +        end;
  +        continue;
  +       end else begin
  +        a.AddChar(ord('-'));
  +       end;
  +      end else if assigned(a) then begin
  +       if not a.IsSingle then begin
  +        if assigned(a.Last) and (a.Last.Lo<=a.Last.Hi) then begin
  +         c:=TFLREUnicodeCharClass.Create(self);
  +         c.AddChar(a.Last.Hi);
  +         c.Canonicalized:=a.Canonicalized;
  +         c.Inverted:=a.Inverted;
  +         result.TakeoverCombine(a);
  +         FreeAndNil(a);
  +         a:=c;
  +        end else begin
  +         FreeAndNil(a);
  +         raise EFLRE.Create('Syntax error');
  +        end;
  +       end;
  +       b:=ParseClassAtom;
  +       if (not b.IsSingle) and (assigned(b.First) and (a.First.Lo<=a.First.Hi)) then begin
  +        c:=TFLREUnicodeCharClass.Create(self);
  +        c.AddChar(b.First.Lo);
  +        c.Canonicalized:=b.Canonicalized;
  +        c.Inverted:=b.Inverted;
  +        result.TakeoverCombine(b);
  +        FreeAndNil(b);
  +        b:=c;
  +       end;
  +       if (not b.IsSingle) or ((assigned(a.Last) and assigned(b.Last)) and not (a.Last.Lo<=b.Last.Hi)) then begin
  +        FreeAndNil(a);
  +        FreeAndNil(b);
  +        raise EFLRE.Create('Syntax error');
  +       end;
  +       if assigned(a.Last) and assigned(b.Last) then begin
  +        a.Last.Hi:=b.Last.Hi;
  +       end else begin
  +        a.TakeoverCombine(b);
  +       end;
  +       FreeAndNil(b);
  +      end;
  +     end;
  +     if assigned(a) then begin
  +      result.TakeoverCombine(a);
  +      FreeAndNil(a);
  +     end;
  +    end;
  +    if (SourcePosition<=SourceLength) and (Source[SourcePosition]=']') then begin
  +     inc(SourcePosition);
  +    end else begin
  +     raise EFLRE.Create('Syntax error');
  +    end;
  +    if (rfCASEINSENSITIVE in Flags) and not result.Canonicalized then begin
  +     result.Canonicalize;
  +    end;
  +    if InvertFlag then begin
  +     result.Invert;
  +    end;
  +   finally
  +    FreeAndNil(a);
  +    FreeAndNil(b);
  +   end;
  +  except
  +   FreeAndNil(result);
  +   raise;
  +  end;
  + end;
    function ParseAtom:PFLRENode;
    var Value,Index:longint;
        Negate,IsSingle,Done,IsNegative,First,Num:boolean;
  -     StartChar,EndChar:ansichar;
  -     CharClass:TFLRECharClass;
  +     StartChar,EndChar,UnicodeChar,LowerCaseUnicodeChar,UpperCaseUnicodeChar:longword;
  +     UnicodeCharClass:TFLREUnicodeCharClass;
        OldFlags:TFLREFlags;
  -     Name,TemporaryString:ansistring;
  -     UnicodeChar,LowerCaseUnicodeChar,UpperCaseUnicodeChar:longword;
  -     TemporaryNodes:array[0..3] of PFLRENode;
  +     Name:ansistring;
    begin
     result:=nil;
     try
  
positive.code: 
       TFLREPrefixCharClasses=array[0..MaxPrefixCharClasses-1] of TFLRECharClass;
      
       TFLREStringIntegerPairHashMapData=longint;
  
       PFLREStringIntegerPairHashMapEntity=^TFLREStringIntegerPairHashMapEntity;
       TFLREStringIntegerPairHashMapEntity=record
  
negative.code:  Add(Key,Value);
  end;
  
  type TFLREUnicodeCharClass=class;
  
       TFLREUnicodeCharClassRange=class
        public
         CharClass:TFLREUnicodeCharClass;
         Previous,Next,Left,Right:TFLREUnicodeCharClassRange;
         Lo,Hi:longword;
         constructor Create(ACharClass:TFLREUnicodeCharClass;ALo,AHi:longword);
         constructor CreateBefore(ACharClass:TFLREUnicodeCharClass;ABefore:TFLREUnicodeCharClassRange;ALo,AHi:longword);
         constructor CreateAfter(ACharClass:TFLREUnicodeCharClass;AAfter:TFLREUnicodeCharClassRange;ALo,AHi:longword);
         destructor Destroy; override;
       end;
  
       TFLREUnicodeCharClassCharSet=set of ansichar;
  
       TFLREUnicodeCharClassRanges=array of TFLREUnicodeCharClassRange;
  
       TFLREUnicodeCharClass=class
        public
         RegExp:TFLRE;
         Previous,Next:TFLREUnicodeCharClass;
         First,Last,Root:TFLREUnicodeCharClassRange;
         CharSet:TFLREUnicodeCharClassCharSet;
         Inverted:longbool;
         Canonicalized:longbool;
         constructor Create(ARegExp:TFLRE);
         destructor Destroy; override;
         procedure Clear;
         procedure Dump;
         procedure DebugDump;
         procedure Optimize;
         procedure AddRange(Lo,Hi:longword;IgnoreCase:boolean=false);
         procedure AddChar(c:longword;IgnoreCase:boolean=false);
         procedure AddUnicodeCategory(CategoryFlags:longword;IgnoreCase:boolean=false);
         procedure AddUnicodeScript(Script:longword;IgnoreCase:boolean=false);
         procedure AddUnicodeBlock(Block:longword;IgnoreCase:boolean=false);
         procedure Combine(From:TFLREUnicodeCharClass);
         function Subtraction(From,SubtractWith:TFLREUnicodeCharClass):boolean;
         function Intersection(From,IntersectWith:TFLREUnicodeCharClass):boolean;
         procedure TakeoverCombine(From:TFLREUnicodeCharClass);
         procedure TakeoverDirtyCombine(From:TFLREUnicodeCharClass);
         procedure Assign(From:TFLREUnicodeCharClass);
         procedure Append(From:TFLREUnicodeCharClass);
         procedure Invert;
         procedure Canonicalize;
         procedure CompileBinarySearchTree;
         procedure CompileCharset;
         procedure Finalize;
         function Count:longword;
         function Contains(c:longword):boolean;
         function Intersects(Other:TFLREUnicodeCharClass):boolean;
         function IsSingle:boolean;
         function HashCode:longword;
         function EqualsTo(OtherObject:TFLREUnicodeCharClass):boolean;
       end;
  
  constructor TFLREUnicodeCharClassRange.Create(ACharClass:TFLREUnicodeCharClass;ALo,AHi:longword);
  begin
   inherited Create;
   CharClass:=ACharClass;
   Lo:=ALo;
   Hi:=AHi;
   if assigned(CharClass.Last) then begin
    Previous:=CharClass.Last;
    CharClass.Last:=self;
    Previous.Next:=self;
    Next:=nil;
   end else begin
    CharClass.First:=self;
    CharClass.Last:=self;
    Previous:=nil;
    Next:=nil;
   end;
   Left:=nil;
   Right:=nil;
  end;
  
  constructor TFLREUnicodeCharClassRange.CreateBefore(ACharClass:TFLREUnicodeCharClass;ABefore:TFLREUnicodeCharClassRange;ALo,AHi:longword);
  begin
   inherited Create;
   CharClass:=ACharClass;
   Lo:=ALo;
   Hi:=AHi;
   Previous:=ABefore.Previous;
   Next:=ABefore;
   ABefore.Previous:=self;
   if assigned(Previous) then begin
    Previous.Next:=self;
   end else begin
    CharClass.First:=self;
   end;
  end;
  
  constructor TFLREUnicodeCharClassRange.CreateAfter(ACharClass:TFLREUnicodeCharClass;AAfter:TFLREUnicodeCharClassRange;ALo,AHi:longword);
  begin
   inherited Create;
   CharClass:=ACharClass;
   Lo:=ALo;
   Hi:=AHi;
   Previous:=AAfter;
   Next:=AAfter.Next;
   AAfter.Next:=self;
   if assigned(Next) then begin
    Next.Previous:=self;
   end else begin
    CharClass.Last:=self;
   end;
  end;
  
  destructor TFLREUnicodeCharClassRange.Destroy;
  begin
   if assigned(Previous) then begin
    Previous.Next:=Next;
   end else if CharClass.First=self then begin
    CharClass.First:=Next;
   end;
   if assigned(Next) then begin
    Next.Previous:=Previous;
   end else if CharClass.Last=self then begin
    CharClass.Last:=Previous;
   end;
   Previous:=nil;
   Next:=nil;
   inherited Destroy;
  end;
  
  constructor TFLREUnicodeCharClass.Create(ARegExp:TFLRE);
  begin
   inherited Create;
   RegExp:=ARegExp;
  {if assigned(RegExp.LastCharClass) then begin
    Previous:=RegExp.LastCharClass;
    RegExp.LastCharClass:=self;
    Previous.Next:=self;
    Next:=nil;
   end else begin
    RegExp.FirstCharClass:=self;
    RegExp.LastCharClass:=self;
    Previous:=nil;
    Next:=nil;
   end;{}
   First:=nil;
   Last:=nil;
   Root:=nil;
   Inverted:=false;
   Canonicalized:=false;
   CharSet:=[];
  end;
  
  destructor TFLREUnicodeCharClass.Destroy;
  begin
   while assigned(First) do begin
    First.Destroy;
   end;
  {if assigned(Previous) then begin
    Previous.Next:=Next;
   end else if RegExp.FirstCharClass=self then begin
    RegExp.FirstCharClass:=Next;
   end;
   if assigned(Next) then begin
    Next.Previous:=Previous;
   end else if RegExp.LastCharClass=self then begin
    RegExp.LastCharClass:=Previous;
   end;{}
   Previous:=nil;
   Next:=nil;
   inherited Destroy;
  end;
  
  procedure TFLREUnicodeCharClass.Clear;
  begin
   while assigned(First) do begin
    First.Destroy;
   end;
   Inverted:=false;
   Canonicalized:=false;
   Root:=nil;
  end;
  
  procedure TFLREUnicodeCharClass.Dump;
  var Range:TFLREUnicodeCharClassRange;
  begin
   Range:=First;
   while assigned(Range) do begin
    writeln(Range.Lo:8,' ',Range.Hi:8);
    Range:=Range.Next;
   end;
  end;
  
  procedure TFLREUnicodeCharClass.DebugDump;
  var Range:TFLREUnicodeCharClassRange;
  begin
   Range:=First;
   while assigned(Range) do begin
    Range:=Range.Next;
   end;
  end;
  
  procedure TFLREUnicodeCharClass.Optimize;
  var Range:TFLREUnicodeCharClassRange;
  begin
   Range:=First;
   while assigned(Range) do begin
    if assigned(Range.Previous) and (((Range.Previous.Hi>=Range.Lo) or ((Range.Previous.Hi+1)=Range.Lo))) then begin
     if Range.Lo>Range.Previous.Lo then begin
      Range.Lo:=Range.Previous.Lo;
     end;
     if Range.Hi<Range.Previous.Hi then begin
      Range.Hi:=Range.Previous.Hi;
     end;
     Range.Previous.Destroy;
     if assigned(Range.Previous) then begin
      Range:=Range.Previous;
     end;
    end else if assigned(Range.Next) and (((Range.Hi>=Range.Next.Lo) or ((Range.Hi+1)=Range.Next.Lo))) then begin
     if Range.Lo>Range.Next.Lo then begin
      Range.Lo:=Range.Next.Lo;
     end;
     if Range.Hi<Range.Next.Hi then begin
      Range.Hi:=Range.Next.Hi;
     end;
     Range.Next.Destroy;
     if assigned(Range.Previous) then begin
      Range:=Range.Previous;
     end;
    end else begin
     Range:=Range.Next;
    end;
   end;
  end;
  
  procedure TFLREUnicodeCharClass.AddRange(Lo,Hi:longword;IgnoreCase:boolean=false);
  var Range:TFLREUnicodeCharClassRange;
      c,cl,cu:longword;
      NeedToCanonicalize:boolean;
  begin
   if IgnoreCase then begin
    NeedToCanonicalize:=false;
    for c:=Lo to Hi do begin
     cl:=UnicodeToLower(c);
     cu:=UnicodeToUpper(c);
     if (cl<>cu) or (cl<>c) or (cu<>c) then begin
      NeedToCanonicalize:=true;
      break;
     end;
    end;
    if NeedToCanonicalize then begin
     for c:=Lo to Hi do begin
      cl:=UnicodeToLower(c);
      cu:=UnicodeToUpper(c);
      if (cl=cu) and (cl=c) then begin
       AddRange(c,c,false);
      end else begin
       AddRange(cl,cl,false);
       AddRange(cu,cu,false);
       if (cl<>c) and (cu<>c) then begin
        AddRange(c,c,false);
       end;
      end;
     end;
    end else begin
     AddRange(Lo,Hi,false);
    end;
   end else begin
    Range:=First;
    while assigned(Range) do begin
     if (Lo>=Range.Lo) and (Hi<=Range.Hi) then begin
      exit;
     end else if (Lo<=Range.Lo) or ((Lo=Range.Lo) and (Hi<=Range.Hi)) then begin
      break;
     end;
     Range:=Range.Next;
    end;
    if assigned(Range) then begin
     TFLREUnicodeCharClassRange.CreateBefore(self,Range,Lo,Hi);
    end else begin
     TFLREUnicodeCharClassRange.Create(self,Lo,Hi);
    end;
    Optimize;
   end;
  end;
  
  procedure TFLREUnicodeCharClass.AddChar(c:longword;IgnoreCase:boolean=false);
  begin
   AddRange(c,c,IgnoreCase);
  end;
  
  procedure TFLREUnicodeCharClass.AddUnicodeCategory(CategoryFlags:longword;IgnoreCase:boolean=false);
  var Value,LowValue,HighValue,Index:longword;
  begin
   LowValue:=$ffffffff;
   HighValue:=0;
   for Value:=0 to $10ffff do begin
    Index:=Value shr FLREUnicodeCategoryArrayBlockBits;
    if (CategoryFlags and (1 shl FLREUnicodeCategoryArrayBlockData[FLREUnicodeCategoryArrayIndexBlockData[FLREUnicodeCategoryArrayIndexIndexData[Index shr FLREUnicodeCategoryArrayIndexBlockBits],Index and FLREUnicodeCategoryArrayIndexBlockMask],Value and FLREUnicodeCategoryArrayBlockMask]))<>0 then begin
     if LowValue<=HighValue then begin
      if (HighValue+1)=Value then begin
       HighValue:=Value;
      end else begin
       AddRange(LowValue,HighValue,IgnoreCase);
       LowValue:=Value;
       HighValue:=Value;
      end;
     end else begin
      LowValue:=Value;
      HighValue:=Value;
     end;
    end;
   end;
   if LowValue<=HighValue then begin
    AddRange(LowValue,HighValue,IgnoreCase);
   end;
  end;
  
  procedure TFLREUnicodeCharClass.AddUnicodeScript(Script:longword;IgnoreCase:boolean=false);
  var Value,LowValue,HighValue,Index:longword;
  begin
   LowValue:=$ffffffff;
   HighValue:=0;
   for Value:=0 to $10ffff do begin
    Index:=Value shr FLREUnicodeScriptArrayBlockBits;
    if Script=FLREUnicodeScriptArrayBlockData[FLREUnicodeScriptArrayIndexBlockData[FLREUnicodeScriptArrayIndexIndexData[Index shr FLREUnicodeScriptArrayIndexBlockBits],Index and FLREUnicodeScriptArrayIndexBlockMask],Value and FLREUnicodeScriptArrayBlockMask] then begin
     if LowValue<=HighValue then begin
      if (HighValue+1)=Value then begin
       HighValue:=Value;
      end else begin
       AddRange(LowValue,HighValue,IgnoreCase);
       LowValue:=Value;
       HighValue:=Value;
      end;
     end else begin
      LowValue:=Value;
      HighValue:=Value;
     end;
    end;
   end;
   if LowValue<=HighValue then begin
    AddRange(LowValue,HighValue,IgnoreCase);
   end;
  end;
  
  procedure TFLREUnicodeCharClass.AddUnicodeBlock(Block:longword;IgnoreCase:boolean=false);
  begin
   AddRange(FLREUnicodeBlocks[Block].FromChar,FLREUnicodeBlocks[Block].ToChar,IgnoreCase);
  end;
  
  procedure TFLREUnicodeCharClass.Combine(From:TFLREUnicodeCharClass);
  var Range:TFLREUnicodeCharClassRange;
  begin
   if assigned(From) then begin
    if assigned(First) then begin
     Canonicalized:=Canonicalized and From.Canonicalized;
    end else begin
     Canonicalized:=From.Canonicalized;
    end;
    Range:=From.First;
    while assigned(Range) do begin
     AddRange(Range.Lo,Range.Hi,false);
     Range:=Range.Next;
    end;
   end;
  end;
                                   
  function TFLREUnicodeCharClass.Subtraction(From,SubtractWith:TFLREUnicodeCharClass):boolean;
  var Range1,Range2:TFLREUnicodeCharClassRange;
      First,Min,Max:longword;
  begin
   result:=false;
   if ((assigned(From) and assigned(SubtractWith)) and (assigned(From.First) and assigned(SubtractWith.First))) and ((From.First.Lo<=SubtractWith.Last.Hi) and (SubtractWith.First.Lo<=From.Last.Hi)) then begin
    Canonicalized:=From.Canonicalized;
    Range1:=From.First;
    while assigned(Range1) do begin
     First:=Range1.Lo;
     Range2:=SubtractWith.First;
     while assigned(Range2) do begin
      if (First<=Range2.Hi) and (Range2.Lo<=Range1.Hi) then begin
       result:=true;
       if First>Range2.Lo then begin
        Min:=First;
       end else begin
        Min:=Range2.Lo;
       end;
       if Range1.Hi<Range2.Hi then begin
        Max:=Range1.Hi;
       end else begin
        Max:=Range2.Hi;
       end;
       if First<Min then begin
        AddRange(First,Min-1,false);
       end;
       First:=Max+1;
      end;
      Range2:=Range2.Next;
     end;
     if First<=Range1.Hi then begin
      AddRange(First,Range1.Hi,false);
     end;
     Range1:=Range1.Next;
    end;
   end;
  end;
  
  function TFLREUnicodeCharClass.Intersection(From,IntersectWith:TFLREUnicodeCharClass):boolean;
  var Range1,Range2:TFLREUnicodeCharClassRange;
      Min,Max:longword;
  begin
   result:=false;
   if ((assigned(From) and assigned(IntersectWith)) and (assigned(From.First) and assigned(IntersectWith.First))) and ((From.First.Lo<=IntersectWith.Last.Hi) and (IntersectWith.First.Lo<=From.Last.Hi)) then begin
    Canonicalized:=From.Canonicalized;
    Range1:=From.First;
    while assigned(Range1) do begin
     Range2:=IntersectWith.First;
     while assigned(Range2) do begin
      if (Range1.Lo<=Range2.Hi) and (Range2.Lo<=Range1.Hi) then begin
       result:=true;
       if Range1.Lo>Range2.Lo then begin
        Min:=Range1.Lo;
       end else begin
        Min:=Range2.Lo;
       end;
       if Range1.Hi<Range2.Hi then begin
        Max:=Range1.Hi;
       end else begin
        Max:=Range2.Hi;
       end;
       if Min<=Max then begin
        AddRange(Min,Max,false);
       end;
      end;
      Range2:=Range2.Next;
     end;
     Range1:=Range1.Next;
    end;
   end;
  end;
  
  procedure TFLREUnicodeCharClass.TakeoverCombine(From:TFLREUnicodeCharClass);
  var SrcRange,NextSrcRange,Range:TFLREUnicodeCharClassRange;
  begin
   if assigned(From) then begin
    if assigned(First) then begin
     Canonicalized:=Canonicalized and From.Canonicalized;
    end else begin
     Canonicalized:=From.Canonicalized;
    end;
    SrcRange:=From.First;
    while assigned(SrcRange) do begin
     Range:=First;
     while assigned(Range) do begin
      if (SrcRange.Lo>=Range.Lo) and (SrcRange.Hi<=Range.Hi) then begin
       exit;
      end else if (SrcRange.Lo<=Range.Lo) or ((SrcRange.Lo=Range.Lo) and (SrcRange.Hi<=Range.Hi)) then begin
       break;
      end;
      Range:=Range.Next;
     end;
     SrcRange.CharClass:=self;
     NextSrcRange:=SrcRange.Next;
     if assigned(SrcRange.Previous) then begin
      SrcRange.Previous.Next:=SrcRange.Next;
     end else if From.First=SrcRange then begin
      From.First:=SrcRange.Next;
     end;
     if assigned(SrcRange.Next) then begin
      SrcRange.Next.Previous:=SrcRange.Previous;
     end else if From.Last=SrcRange then begin
      From.Last:=SrcRange.Previous;
     end;
     SrcRange.Previous:=nil;
     SrcRange.Next:=nil;
     if assigned(Range) then begin
      SrcRange.Previous:=Range.Previous;
      SrcRange.Next:=Range;
      Range.Previous:=SrcRange;
      if assigned(SrcRange.Previous) then begin
       SrcRange.Previous.Next:=SrcRange;
      end else begin
       SrcRange.CharClass.First:=SrcRange;
      end;
     end else begin
      if assigned(SrcRange.CharClass.Last) then begin
       SrcRange.Previous:=SrcRange.CharClass.Last;
       SrcRange.CharClass.Last:=SrcRange;
       SrcRange.Previous.Next:=SrcRange;
       SrcRange.Next:=nil;
      end else begin
       SrcRange.CharClass.First:=SrcRange;
       SrcRange.CharClass.Last:=SrcRange;
       SrcRange.Previous:=nil;
       SrcRange.Next:=nil;
      end;
     end;
     Optimize;
     SrcRange:=NextSrcRange;
    end;
   end;
  end;
  
  procedure TFLREUnicodeCharClass.TakeoverDirtyCombine(From:TFLREUnicodeCharClass);
  var SrcRange:TFLREUnicodeCharClassRange;
  begin
   if assigned(From) then begin
    if assigned(First) then begin
     Canonicalized:=Canonicalized and From.Canonicalized;
    end else begin
     Canonicalized:=From.Canonicalized;
    end;
    SrcRange:=From.First;
    while assigned(SrcRange) do begin
     SrcRange.CharClass:=self;
     SrcRange:=SrcRange.Next;
    end;
    if assigned(Last) then begin
     Last.Next:=From.First;
     From.First.Previous:=Last;
     Last:=From.Last;
    end else begin
     First:=From.First;
     Last:=From.Last;
    end;
    From.First:=nil;
    From.Last:=nil;
   end;
  end;
  
  procedure TFLREUnicodeCharClass.Assign(From:TFLREUnicodeCharClass);
  var Range:TFLREUnicodeCharClassRange;
  begin
   if assigned(From) then begin
    while assigned(First) do begin
     First.Destroy;
    end;
    Inverted:=From.Inverted;
    Canonicalized:=From.Canonicalized;
    Range:=From.First;
    while assigned(Range) do begin
     Range.CharClass:=self;
     Range:=Range.Next;
    end;
    First:=From.First;
    Last:=From.Last;
    From.First:=nil;
    From.Last:=nil;
   end;
  end;
  
  procedure TFLREUnicodeCharClass.Append(From:TFLREUnicodeCharClass);
  var Range:TFLREUnicodeCharClassRange;
  begin
   if assigned(From) then begin
    Range:=From.First;
    while assigned(Range) do begin
     TFLREUnicodeCharClassRange.Create(self,Range.Lo,Range.Hi);
     Range:=Range.Next;
    end;
   end;
  end;
  
  procedure TFLREUnicodeCharClass.Invert;
  var NewList:TFLREUnicodeCharClass;
      Range:TFLREUnicodeCharClassRange;
      Lo,Hi:longword;
  begin
   Optimize;
   Inverted:=not Inverted;
   if assigned(First) and (First=Last) and (First.Lo=0) and (First.Hi=$ffffffff) then begin
    First.Destroy;
   end else if not assigned(First) then begin
    TFLREUnicodeCharClassRange.Create(self,0,$ffffffff);
   end else begin
    NewList:=TFLREUnicodeCharClass.Create(RegExp);
    try
     Range:=First;
     if Range.Lo>0 then begin
      TFLREUnicodeCharClassRange.Create(NewList,0,Range.Lo-1);
     end;
     Lo:=Range.Hi;
     Range:=Range.Next;
     while assigned(Range) do begin
      if (Lo+1)<Range.Lo then begin
       Hi:=Range.Lo;
       TFLREUnicodeCharClassRange.Create(NewList,Lo+1,Hi-1);
      end;
      Lo:=Range.Hi;
      Range:=Range.Next;
     end;
     if Lo<>$ffffffff then begin
      TFLREUnicodeCharClassRange.Create(NewList,Lo+1,$ffffffff);
     end;
     while assigned(First) do begin
      First.Destroy;
     end;
     Range:=NewList.First;
     while assigned(Range) do begin
      Range.CharClass:=self;
      Range:=Range.Next;
     end;
     First:=NewList.First;
     Last:=NewList.Last;
     NewList.First:=nil;
     NewList.Last:=nil;
     Range:=First;
     while assigned(Range) do begin
      Range.CharClass:=self;
      Range:=Range.Next;
     end;
    finally
     NewList.Destroy;
    end;
   end;
  end;
  
  procedure TFLREUnicodeCharClass.Canonicalize;
  var NewList:TFLREUnicodeCharClass;
      Range:TFLREUnicodeCharClassRange;
      OldInverted:boolean;
  begin
   if not Canonicalized then begin
    NewList:=TFLREUnicodeCharClass.Create(RegExp);
    try
     OldInverted:=Inverted;
     if Inverted then begin
      Invert;
     end;
     Range:=First;
     while assigned(Range) do begin
      NewList.AddRange(Range.Lo,Range.Hi,true);
      Range:=Range.Next;
     end;
     while assigned(First) do begin
      First.Destroy;
     end;
     First:=NewList.First;
     Last:=NewList.Last;
     NewList.First:=nil;
     NewList.Last:=nil;
     Range:=First;
     while assigned(Range) do begin
      Range.CharClass:=self;
      Range:=Range.Next;
     end;
     if OldInverted then begin
      Invert;
     end;
     Inverted:=OldInverted;
    finally
     NewList.Destroy;
    end;
    Canonicalized:=true;
   end;
  end;
  
  procedure TFLREUnicodeCharClass.CompileBinarySearchTree;
  type PTFLREUnicodeCharClassRange=^TFLREUnicodeCharClassRange;
  var Ranges:TFLREUnicodeCharClassRanges;
   procedure Process(Parent:PTFLREUnicodeCharClassRange;LowIndex,HighIndex:longint);
   var Middle:longint;
   begin
    while LowIndex<=HighIndex do begin
     Middle:=(LowIndex+HighIndex) div 2;
     Parent^:=Ranges[Middle];
     case HighIndex-LowIndex of
      0:begin
       break;
      end;
      1:begin
       if Middle=LowIndex then begin
        Parent:=@Parent^.Right;
        LowIndex:=Middle+1;
       end else begin
        Parent:=@Parent^.Left;
        HighIndex:=Middle-1;
       end;
      end;
      else begin
       Process(@Parent^.Left,LowIndex,Middle-1);
       Parent:=@Parent^.Right;
       LowIndex:=Middle+1;
      end;
     end;
    end;
   end;
  var Range:TFLREUnicodeCharClassRange;
      Count:longint;
  begin
   Root:=nil;
   Ranges:=nil;
   try
    Count:=0;
    Range:=First;
    while assigned(Range) do begin
     inc(Count);
     Range:=Range.Next;
    end;
    SetLength(Ranges,Count);
    Count:=0;
    Range:=First;
    while assigned(Range) do begin
     Ranges[Count]:=Range;
     inc(Count);
     Range:=Range.Next;
    end;
    if Count>0 then begin
     Process(@Root,0,Count-1);
    end;
   finally
    SetLength(Ranges,0);
   end;
  end;
  
  procedure TFLREUnicodeCharClass.CompileCharset;
  var Range:TFLREUnicodeCharClassRange;
  begin
   CharSet:=[];
   Range:=First;
   while assigned(Range) and (Range.Lo<256) do begin
    if Range.Lo=Range.Hi then begin
     System.Include(CharSet,ansichar(byte(Range.Lo)));
    end else begin
     if Range.Hi<256 then begin
      CharSet:=CharSet+[ansichar(byte(Range.Lo))..ansichar(byte(Range.Hi))];
     end else begin
      CharSet:=CharSet+[ansichar(byte(Range.Lo))..#$ff];
     end;
    end;
    Range:=Range.Next;
   end;
  end;
  
  procedure TFLREUnicodeCharClass.Finalize;
  begin
   CompileCharset;
   CompileBinarySearchTree;
  end;
  
  function TFLREUnicodeCharClass.Count:longword;
  var Range:TFLREUnicodeCharClassRange;
  begin
   result:=0;
   Range:=First;
   while assigned(Range) do begin
    inc(result,(Range.Hi-Range.Lo)+1);
    Range:=Range.Next;
   end;
  end;
  
  function TFLREUnicodeCharClass.Contains(c:longword):boolean;
  var Range:TFLREUnicodeCharClassRange;
  begin
   result:=false;
   Range:=Root;
   if assigned(Range) and ((c>=First.Lo) and (c<=Last.Hi)) then begin
    if First=Last then begin
     result:=true;
     exit;
    end else begin
     if c<256 then begin
      result:=ansichar(byte(c)) in CharSet;
     end else begin
      repeat
       if (c>=Range.Lo) and (c<=Range.Hi) then begin
        result:=true;
        break;
       end;
       if c<Range.Lo then begin
        Range:=Range.Left;
        continue;
       end;
       if Range.Hi<c then begin
        Range:=Range.Right;
        continue;
       end;
       result:=false;
       break;
      until not assigned(Range);
     end;
    end;
   end;
  end;
  
  function TFLREUnicodeCharClass.Intersects(Other:TFLREUnicodeCharClass):boolean;
  var Range1,Range2:TFLREUnicodeCharClassRange;
  begin
   result:=false;
   if (assigned(Other) and (assigned(First) and assigned(Other.First))) and ((First.Lo<=Other.Last.Hi) and (Other.First.Lo<=Last.Hi)) then begin
    Range1:=First;
    while assigned(Range1) do begin
     Range2:=Other.First;
     while assigned(Range2) do begin
      if (Range1.Lo<=Range2.Hi) and (Range2.Lo<=Range1.Hi) then begin
       result:=true;
       exit;
      end;
      Range2:=Range2.Next;
     end;
     Range1:=Range1.Next;
    end;
   end;
  end;
  
  function TFLREUnicodeCharClass.IsSingle:boolean;
  begin
   result:=(First=Last) and ((assigned(First) and (First.Lo=First.Hi)) or not assigned(First));
  end;
  
  function TFLREUnicodeCharClass.HashCode:longword;
  var Range:TFLREUnicodeCharClassRange;
      h,i:longword;
  begin
   result:=$811c9dc5;
   Range:=First;
   h:=0;
   while assigned(Range) do begin
    inc(h);
    Range:=Range.Next;
   end;
   Range:=First;
   while assigned(Range) do begin
    i:=((Range.Hi and $ffff) shl 16) or (Range.Lo and $ffff);
    h:=(h xor i) xor $2e63823a;
    inc(h,(h shl 15) or (h shr (32-15)));
    dec(h,(h shl 9) or (h shr (32-9)));
    inc(h,(h shl 4) or (h shr (32-4)));
    dec(h,(h shl 1) or (h shr (32-1)));
    h:=h xor (h shl 2) or (h shr (32-2));
    result:=result xor i;
    inc(result,(result shl 1)+(result shl 4)+(result shl 7)+(result shl 8)+(result shl 24));
    i:=(Range.Hi and $ffff0000) or ((Range.Lo and $ffff0000) shr 16);
    h:=(h xor i) xor $2e63823a;
    inc(h,(h shl 15) or (h shr (32-15)));
    dec(h,(h shl 9) or (h shr (32-9)));
    inc(h,(h shl 4) or (h shr (32-4)));
    dec(h,(h shl 1) or (h shr (32-1)));
    h:=h xor (h shl 2) or (h shr (32-2));
    result:=result xor i;
    inc(result,(result shl 1)+(result shl 4)+(result shl 7)+(result shl 8)+(result shl 24));
    Range:=Range.Next;
   end;
   result:=result xor h;
   if result=0 then begin
    result:=$ffffffff;
   end;
  end;
  
  function CompareCharClasses(c1,c2:TFLREUnicodeCharClass):longint;
  var r1,r2:TFLREUnicodeCharClassRange;
  begin
   r1:=c1.First;
   r2:=c2.First;
   while assigned(r1) and assigned(r2) do begin
    if r1.Lo<>r2.Lo then begin
     result:=longint(r1.Lo)-longint(r2.Lo);
     exit;
    end;
    if r1.Hi<>r2.Hi then begin
     result:=longint(r1.Hi)-longint(r2.Hi);
     exit;
    end;
    r1:=r1.Next;
    r2:=r2.Next;
   end;
   if assigned(r1) then begin
    result:=1;
   end else if assigned(r2) then begin
    result:=-1;
   end else begin
    result:=0;
   end;
  end;
  
  function TFLREUnicodeCharClass.EqualsTo(OtherObject:TFLREUnicodeCharClass):boolean;
  begin
   result:=CompareCharClasses(self,TFLREUnicodeCharClass(OtherObject))=0;
  end;
  
  constructor TFLRE.Create(const ARegularExpression:ansistring;const AFlags:TFLREFlags=[]);
  var FLREDFAStateCreateTempDFAState:TFLREDFAState;
  begin
  