//*********************************************************************
//*                 UTF7_to_UTF8_Converter 2021-10-24                 *
//*                   >> OnBeforeSendingMessage <<                    *
//*                                                                   *
//* Dieses Script wandelt UTF7 in UTF8 und verschickt das Posting in  *
//* UTF8! DIALOG selbst beherrscht UTF8 nur bis U+FFFF! Danach        *
//* produziert dieses Programm nur noch "komische Zeichen", welche    *
//* nur DIALOG durch eine Negation der Negation selbst entschlüsseln  *
//* kann!                                                             *
//*       !! DIESES SCRIPT BEHEBT DIESEN GRAVIERENDEN FEHLER !!       *
//*                                                                   *
//* Funktionalitaet: [ ] neutral                                      *
//*                  [ ] nur Basis_Modul                              *
//*                  [x] nur Pathfinder                               *
//*                                                                   *
//* Datum     : 31.07.2020  (Corona-Zeit)                             *
//* Stand     : 24.10.2021                                            *
//* Autor     : Thomas Barghahn                                       *
//*                                                                   *
//* DateiName : _i_OBSendM_UTF7_to_UTF8_Converter.ds                  *
//* Einbindung: {$I _i_OBSendM_UTF7_to_UTF8_Converter.ds}             *
//* Aufruf    :                                                       *
//*   Result := Convert_UTF7_to_UTF8 (Result, Message, Error_Func);   *
//*********************************************************************

Procedure Init_Convert_UTF7_to_UTF8 (var CTH_Quote_Marks  : Boolean;
                                     var Check_Subject    : Boolean;
                                     var Box_Double_Line  : Boolean;
                                     var Debug_Reports    : Byte);


Begin
//{-------------------------------------------------------------------}
//{                 Anwenderspezifische Einstellungen                 }
//{-------------------------------------------------------------------}

// Soll der Subject-Header auf uncodierte Zeichen geprueft werden?
// Gleichzeitig wird auch die Laenge des Headers geprueft und ggf.
// korrigiert.
// Setze True oder False
// Check_Subject := False; // das Subject wird *nicht* geprueft
Check_Subject := True; // das Subject wird geprueft

// Soll der Content-Type Header wie folgt geändert werden?
// Beispiel mit Quote_Marks:
// Content-Type: text/plain; charset="utf-8"
// Setze True oder False
CTH_Quote_Marks := False; // Quote_Marks bleiben wie im Bsp erhalten

// Sollen gefundene Boxen mit einer Doppellinie ausgefuehrt werden?
// Setze True oder False
Box_Double_Line := True;

// Auf welcher Meldungs-Ebene sollen Reports des Converters erscheinen?
// Ebenen 0..7 werden akzeptiert
Debug_Reports := 3;  // Ebene 4 waere z.B. gelb (Warnung)
                     // Ebene 7 zeigt die gewählte Ebene (z.B. Ebene 4
                     // und Meldungen der Scripte, die Ebene 7
                     // nutzen! --> Ausgabe schwarz auf weiß

//{-------------------------------------------------------------------}
//{                       Ende der Einstellungen                      }
//{-------------------------------------------------------------------}
End;

//{===================================================================}
//{           !!!  Ab hier bitte nichts mehr ändern  !!!              }
//{===================================================================}

//--[ START Function Convert_UTF7_to_UTF8 ]----------------------------

type Lines_of_Box  = record
   Str_UTF7_Chars  : Integer;
   Str_UTF8_Chars  : Integer;
   Cursor_Pos      : Integer;    // oder das Ende einer Zeile
   Total_length    : Integer;    // totale Laenge einer Zeile (ROH UTF-7)
   Int_Line_Length : integer;    // *alle* Zeichen *einer* Zeile innerhalb der Box - UTF7 + UTF8
end; // of record

//const 
//   DBL_Upper_left_corner = $E2+$95+$94; // Ecke oben links

Function Convert_UTF7_to_UTF8  (fbkResult  : Boolean;
                                Msg        : TStringList;
                                Error_Func : String) : Boolean;

var Intk : Integer;                      // Allgemeiner Zaehler
    Intz : Integer;                      // Zeile
    Ints : Integer;                      // Spalte
    Inti : Integer;                      // Allgemeiner Zaehler
    Inta : Integer;                      // Allgemeiner Zaehler
    Int_SP : Integer;                    // Startposition (StartTag) in einer Zeile
    Int_EP : Integer;                    // Endposition (EndTag) in einer Zeile
    Int_SB : Integer;                    // Startzeile Body
    Int_MCount : Integer;                // Endzeile Body (End of Message)
    Int_PCT : Integer;                   // Position des Content-Type-Headers
    Str_UTF8 : string;                   // UTF8 String (das Ergebnis der Codierung)
    Str_UTF7 : String;                   // UTF7 String (der zu verarbeitende String)
    Str_Bin : String;                    // UTF7 String (binaer)
    Str_Hex : String;                    // UTF8 String (hexadezimal)
    Bool_PM : Boolean;                   // "+-" gefunden (PM = Plus Minus)
    UTF8_CharSet : String;               // ersetzt den UTF7-String
    Bool_CTH_Marks : Boolean;            // Qoute_Marks setzen?
    Bool_Check_Subj : Boolean;           // soll das Subject geprüft werden?
    Bool_Box_Double_Line : Boolean;      // Ausfuehrung von Boxen mit doppelter Linie
    Str_CTH : String;                    // Aussehen des Content-Type-Headers
    Debug_Reports : Byte;                // Meldungsebene im Statusfenster von Dialog                   
    Char_B64 : Set of Char;              // CharSet nach RFC 2152
    Bool_Box : Boolean;                  // wird in einer Box(-Quote) konvertiert
    Chars_in_Str_UTF8 : Integer;         // Anzahl der Zeichen im Str_UTF8 String ( Anzahl 1, 2, 3 und 4 Byte-Zeichen)
    Chars_in_Str_UTF7 : Integer;         // Anzahl der Bytes im Str_UTF7 String ( Anzahl in der Sequenz "+ ... -")
    Text_Box : array [0..49] of 
     Lines_of_Box;                       // dynamisches Array fur die Zeilen einer Box
    Box_Line : Integer;                  // Zeile der Box
    Int_Length_BoxLine : Integer;        // *alle* Zeichen *einer* Zeile innerhaln der Box!
    Max_Length_BoxLine : Integer;        // maximal erforderliche Laenge einer Boxzeile nach Austausch
    Max_Int_Line_Length : Integer;       // maximale Anzahl von Zeichen in einer Zeile *innerhalb* einer Box
    Diff_Length         : Integer;       // Differenz einer Zeile zu der optimalen Laenge einer Box
    Box_ULC : String;                    // Box_Upper_Left_Corner - Box links oben
    Box_URC : String;                    // Box_Upper_Right_Corner - Box rechts oben
    Box_BLC : String;                    // Box_Bottom_Left_Corner - Box links unten
    Box_BRC : String;                    // Box_Bottom_Right_Corner - Box rechts unten
    Box_BHL : String;                    // Box_Header_Left - Box Kopf links
    // Plus_Char : Integer;                 // "+-" auffuellen mit einem Zeichen
    // Box_BHR : String;                    // Box_Header_Right - Box Kopf rechts
    
Begin
   // Rückgabewert entsprechend vorheriger Scriptprobleme setzen
   Result := fbkResult;

   // Wenn bereits irgendein Script einen Fehler verursacht hat,
   // dann braucht dieses hier nicht mehr ausgeführt werden
   If Not Result Then begin
      WriteToLog ('==== ANFANG =======================================' ,4);     
      WriteToLog ('Script *** UTF7_to_UTF8_Converter *** wurde nicht mehr ausgefuehrt' ,4);
      WriteToLog ('Script ' + Error_Func + ' hat diesen Fehler verursacht!' ,4);
      WriteToLog ('==== ENDE =========================================' ,4);     
      Exit;
   end;   

   Try
      Box_ULC := chr($E2)+chr($95)+chr($94);
      Box_URC := chr($E2)+chr($95)+chr($97);
      Box_BLC := chr($E2)+chr($95)+chr($9A);
      Box_BRC := chr($E2)+chr($95)+chr($9D);
      Box_BHL := chr($E2)+chr($95)+chr($9D);
//      Box_BHR := 
      
      Bool_Box := False;
      Bool_PM := False;
      // +2D3eAADk2DTdHgD8AN/YNd1t-										
      Int_PCT := GetHeaderLine ('Content-Type:',Msg);
      If AnsiPos ('utf-7', Msg[Int_PCT]) > 0 then begin
         Init_Convert_UTF7_to_UTF8 (Bool_CTH_Marks, Bool_Check_Subj, Bool_Box_Double_Line,
                                    Debug_Reports);
         WriteToLog ('Script Convert_UTF7_to_UTF8 läuft' ,Debug_Reports);
         If Bool_CTH_Marks = True then
            Str_CTH := 'Content-Type: text/plain; charset=' + '"' + 'utf-8' + '"; format=fixed'
         Else
            Str_CTH := 'Content-Type: text/plain; charset=utf-8; format=fixed';               

	       Char_B64 := ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
                      'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
                      '0','1','2','3','4','5','6','7','8','9','/','+'];
         Int_SB := Msg.IndexOf('') + 1;        // Anfang der Msg
         Int_MCount := Msg.Count;              // Ende der Message
         Intz := Int_SB;
         Ints := 1;
         Box_Line := -1;
         Max_Length_BoxLine := 0;
         Int_Length_BoxLine := 0;
         WriteToLog ('Int_SB, Int_MCount  : ' + IntToStr(Int_SB) + '  ' + IntToStr(Int_MCount), Debug_Reports);
         While Intz < Int_MCount do begin
         	  Chars_in_Str_UTF8 := 0;
         	  Chars_in_Str_UTF7 := 0;
         	  // WriteToLog (Msg[Intz], 4);
            // sind wir in einer *geschlossenen* Box?
            If length(Msg[Intz]) > 0 then begin
               If Bool_Box then begin
                  Int_Length_BoxLine := length (Trim (copy (Msg[Intz], 3, length(Msg[Intz]) - 3))) + 4;
         	        If Int_Length_BoxLine < 15 then Int_Length_BoxLine := 15;
                  Text_Box[Box_Line].Total_Length := length(Msg[Intz]);
               end;   
         	     If (copy (Msg[Intz], 1, 3) = ',--') and (Msg[Intz][length(Msg[Intz])] = '.') then begin
                  For Inta := 0 to 49 do Begin
                     Text_Box[Inta].Str_UTF7_Chars  := 0;
                     Text_Box[Inta].Str_UTF8_Chars  := 0;
                     Text_Box[Inta].Cursor_Pos      := 0;
                     Text_Box[Inta].Total_length    := 0;
                     Text_Box[Inta].Int_Line_Length := 0;
                  end; // For
         	        Bool_Box := True;
         	        Max_Int_Line_Length := 0;
                  Max_Length_BoxLine := 0;
         	        If ansipos (']', Msg[Intz]) > 0 then
         	           Int_Length_BoxLine :=  length (copy (Msg[Intz], 1, ansipos (']', Msg[Intz]))) + 6
         	        else
         	           Int_Length_BoxLine := 15;
         	        If Int_Length_BoxLine < 15 then Int_Length_BoxLine := 15;
         	     end; // If   
               If (copy (Msg[Intz], 1, 3) = '`--') and (Msg[Intz][length(Msg[Intz])] = '''') then begin
         	        Bool_Box := False;
         	        Box_Line := Box_Line + 1;
         	        // SetLength (Text_Box, Box_Line);
         	        Text_Box[Box_Line].Total_Length := length(Msg[Intz]);
                  For Inta := 0 to Box_Line  do begin
                  	 If Max_Length_BoxLine < Text_Box[Inta].Total_Length Then begin
                  	 	  Max_Length_BoxLine := Text_Box[Inta].Total_Length;
                  	 end;
         	           Text_Box[Inta].Cursor_Pos := Text_Box[Inta].Total_Length - Text_Box[Inta].Str_UTF7_Chars +
         	                                        Text_Box[Inta].Str_UTF8_Chars;
                  	 WriteToLog ('*** Box-Zeilenlaengen *** : ' + IntToStr(Inta) + '  ' + IntToStr (Text_Box[Inta].Total_Length), 4);	   
                     WriteToLOg ('*** Zeichen im UTF7-Code *** : ' + IntToStr (Text_Box[Inta].Str_UTF7_Chars), Debug_Reports);
                     WriteToLOg ('*** Zeichen im UTF8-Code *** : ' + IntToStr (Text_Box[Inta].Str_UTF8_Chars), Debug_Reports);
                     WriteToLOg ('*** Position des Cursors *** : ' + IntToStr (Text_Box[Inta].Cursor_Pos), Debug_Reports);
                     WriteToLog ('*** Int_Line_Length      *** : ' + IntToStr (Text_Box[Inta].Int_Line_Length), Debug_Reports);  
                     WriteToLog ('*** Max-Length-BoxLine   *** : ' + IntToStr (Max_Length_BoxLine), Debug_Reports);
                     WriteToLog ('*** Max_Int_Line_Length  *** : ' + IntToStr (Max_Int_Line_Length), Debug_Reports);
                     WriteToLog ('', 4);
                  end; // For
                  For Inta := (Box_Line) downto 0 do begin
                     Diff_Length := Text_Box[Inta].Cursor_Pos - (Max_Int_Line_Length);
                  	 If Diff_Length < 0 Then Diff_Length := -Diff_Length * 1;
                     WriteToLog ('*** Diff_Length         ***  : ' + IntToStr (Diff_Length), Debug_Reports);
                 	   If Max_Int_Line_Length < Text_Box[Inta].Cursor_Pos then begin
                   	 	  For Inti := 1 to Diff_Length do begin
                   	 	     Msg[Intz+Inta-Box_Line] := copy ( Msg[Intz+Inta-Box_Line], 1, length (Msg[Intz+Inta-Box_Line]) - 2) +
                   	 	                       copy ( Msg[Intz+Inta-Box_Line], length (Msg[Intz+Inta-Box_Line]), 1);
                   	 	  end;
                     end; // If
                 	   If Max_Int_Line_Length > Text_Box[Inta].Cursor_Pos then begin
                   	 	  For Inti := 1 to Diff_Length do begin
                   	 	     Msg[Intz+Inta-Box_Line] := copy ( Msg[Intz+Inta-Box_Line], 1, length (Msg[Intz+Inta-Box_Line]) - 1) +
                   	 	                       copy ( Msg[Intz+Inta-Box_Line], length (Msg[Intz+Inta-Box_Line]) - 1, 1) +
                   	 	                       copy ( Msg[Intz+Inta-Box_Line], length (Msg[Intz+Inta-Box_Line]), 1);
                   	 	  end;
                     end; // If
                     // Doppellinien einfuegen
                     If Bool_Box_Double_Line then begin
                        If (Inta = 0) then begin
                        	 // die Ecken oben
                           Msg[Intz+Inta-Box_Line] := chr($E2)+chr($95)+chr($94) + copy (Msg[Intz+Inta-Box_Line], 2, length (Msg[Intz+Inta-Box_Line]) - 2) + 
                           chr($E2)+chr($95)+chr($97);
                           // Msg[Intz+Inta-Box_Line] := DBL_Upper_left_corner + copy (Msg[Intz+Inta-Box_Line], 2, length (Msg[Intz+Inta-Box_Line]) - 2) + 
                           // chr($E2)+chr($95)+chr($97);
                           if ansipos ('[', Msg[Intz+Inta-Box_Line]) > 0 then begin
                        	    Msg[Intz+Inta-Box_Line] := StringReplace(copy(Msg[Intz+Inta-Box_Line],1, ansipos('[', Msg[Intz+Inta-Box_Line])), '-', chr($E2)+chr($95)+chr($90), [rfReplaceAll]) +
                        	    copy (Msg[Intz+Inta-Box_Line], ansipos('[', Msg[Intz+Inta-Box_Line]) + 1, ansipos(']', Msg[Intz+Inta-Box_Line]) - ansipos('[', Msg[Intz+Inta-Box_Line])) +
                        	    StringReplace(copy(Msg[Intz+Inta-Box_Line], ansipos(']', Msg[Intz+Inta-Box_Line]) + 1, length(Msg[Intz+Inta-Box_Line])), '-', chr($E2)+chr($95)+chr($90), [rfReplaceAll]);
                              Msg[Intz+Inta-Box_Line] := StringReplace(Msg[Intz+Inta-Box_Line], '[', chr($E2)+chr($95)+chr($9D), [rfIgnoreCase]);
                              Inti := length (Msg[Intz+Inta-Box_Line]);
                              while Inti > 0 do begin
                                 If Msg[Intz+Inta-Box_Line][Inti] = ']' then begin 
                                 	  Msg[Intz+Inta-Box_Line] := copy (Msg[Intz+Inta-Box_Line], 1, Inti - 1) + 
                                 	  chr($E2)+chr($95)+chr($9A) + copy (Msg[Intz+Inta-Box_Line], Inti + 1, length (Msg[Intz+Inta-Box_Line]));
                                 	  Inti := 1;
                                 end;	   
                              Inti := Inti - 1;
                              end   
                           end else
                              Msg[Intz+Inta-Box_Line] := StringReplace(Msg[Intz+Inta-Box_Line], '-', chr($E2)+chr($95)+chr($90), [rfReplaceAll])
                        // die Ecken und Linie unten
                        end Else If (Inta = Box_Line) then begin
                           Msg[Intz+Inta-Box_Line] := StringReplace(Msg[Intz+Inta-Box_Line], '`', chr($E2)+chr($95)+chr($9A), [rfReplaceAll]);
                           Msg[Intz+Inta-Box_Line] := StringReplace(Msg[Intz+Inta-Box_Line], '''', chr($E2)+chr($95)+chr($9D), [rfReplaceAll]);                        
                           Msg[Intz+Inta-Box_Line] := StringReplace(Msg[Intz+Inta-Box_Line], '-', chr($E2)+chr($95)+chr($90), [rfReplaceAll])
                        end Else IF (Inta <> Box_Line) and (Inta <> 0) then begin
                           Msg[Intz+Inta-Box_Line] := chr($E2)+chr($95)+chr($91) + 
                                                      copy (Msg[Intz+Inta-Box_Line], 2 , length (Msg[Intz+Inta-Box_Line]) - 2) +
                                                      chr($E2)+chr($95)+chr($91);
                        end ; // IF
                     end; ; // If Double_Line    	 
                  end; // For Inta := (Box_Line) downto 0 ...
         	        Box_Line := -1;	
         	        // WriteToLog ('Zeile und Laenge ' + IntToStr(Intz - 1) + '   ' + IntToStr ( length ( Msg[Intz - 1])), 4);
         	     end; // If (copy (Msg[Intz], 1, 3) = '`--') and ...  (ENDE Box) 
            end; // If length(Msg[Intz]) > 0 ...
            // !!!ALLE "+-" GEGEN "*~~~~*" AUSTAUSCHEN! DIESE WERDEN UNTEN DURCH EIN '+' WIEDER EINFEFUEGT!!!
            // Ausgesetzt am 05.10.2021
            Inti := 1;
            {
            while Inti <= length(Msg[Intz]) do begin
	             // auf hochgestellte Zahlen achten!
	             If (Msg[Intz][Inti] = '+') then begin
	 	              if (copy (Msg[Intz], Inti - 8, 3) <> '+IH') and (copy (Msg[Intz], Inti - 8, 3) <> '+AL') and
	 	                 (not (Msg[Intz][Inti + 1] in Char_B64)) then begin
	 	                  Msg[Intz] := copy (Msg[Intz], 1, Inti - 1) + '*~~~~*'	+ copy (Msg[Intz], Inti + 2, length(Msg[Intz]) - Inti + 1);
	 	                  Chars_in_Str_UTF8 := Chars_in_Str_UTF8 - 1; // aus "+-" wird am Ende wieder "+"
	 	                  Inti := Inti + 5;
	 	              end; // If	 
	             end; // If
	             Inti := Inti + 1;
            end; // while auf hochgestellte Zahlen achten!
            }
            // den UTF7-Start_Tag "+" suchen ...
            WriteToLog ('Ich bin in Zeile : ' + IntToStr(Intz - Int_SB + 1), Debug_Reports);
            While Ints < length(Msg[Intz]) do begin
               WriteToLog ('Ich bin in Zeile : ' + IntToStr(Intz - Int_SB + 1) + ' Ich bin in Spalte : ' + IntToStr(Ints), Debug_Reports);
               If (Msg[Intz][Ints] = '+') and (Msg[Intz][Ints + 1] <> '-') and (Msg[Intz][Ints + 1] <> ' ') then begin
                  Int_SP := Ints;
                  Intk := Int_SP + 1;
                  WriteToLog ('Anfang in Zeile und Spalte:  ' + IntToStr(Intz - Int_SB + 1) + '  ' + IntToStr(Int_SP) + ' gefunden!', Debug_Reports);
                  // den UTF7-End_Tag suchen ...
                  While Intk <= length (Msg[Intz]) do begin
                           WriteToLog ('Laenge der Zeile: ' + IntToStr(length (Msg[Intz])), Debug_Reports);
                     If Msg[Intz][Intk] = '-' then begin
                        Int_EP := Intk;
                           WriteToLog ('Ende in Spalte: ' + IntToStr(Int_EP) + ' gefunden!', Debug_Reports);
                        Str_UTF7 := copy (Msg[Intz], Int_SP, Int_EP - Int_Sp + 1);
                        Chars_in_Str_UTF7 := Chars_in_Str_UTF7 + length (Str_UTF7);
                        Str_Bin := '';
                        Str_Hex := '';
                        Str_UTF8 := '';
                        MyAscToBin(Str_UTF7, Str_Bin, Debug_Reports);
                        MyConvertBinGroupToHexGroup (Str_Bin, Str_Hex, Debug_Reports);
                        MyHexTo_UTF8 (Str_Hex, Str_UTF8, Debug_Reports);
                        // Anzahl der Bytes im Str_UTF8 String ermitteln
                        Inta := 6;
                        // chr($F0)+chr($9D)+chr($95)+chr($BF)+chr($F0)+chr($9D)+chr($96)+chr($8D)+
                        If (length (Str_UTF8) > 0) and (Bool_Box = True) then begin
                           while Inta <= (length (Str_UTF8) - 3)  do begin
                           	  Case Str_UTF8[Inta] of
                           	     'C','D' : begin
                           	     	            If (UTF8_Code_to_dec (copy (Str_UTF8, Inta, 2) + copy (Str_UTF8, Inta + 9, 2)) >= 768) and
                           	     	               (UTF8_Code_to_dec (copy (Str_UTF8, Inta, 2) + copy (Str_UTF8, Inta + 9, 2)) <= 879) then
                           	     	                  Chars_in_Str_UTF8 := Chars_in_Str_UTF8 - 1;
                           	     	            Inta := Inta + 18;
                           	     	         end;   
                           	         'E' : begin
                           	         	        Inta := Inta + 27;
                           	         	     end;
                           	         'F' : begin
                           	         	        Inta := Inta + 36;
                           	     	         end
                           	     	   Else
                           	     	            Inta := Inta + 9;
                           	  end; // case   	               
                           	  Chars_in_Str_UTF8 := Chars_in_Str_UTF8 + 1;       	        
                           end; // while
                           // Anzahl Zeichen im Str_UTF8 String
                        end; // If
                        WriteToLog ('*** HAUPTPROGRAMM Str_Hex  : ' + Str_Hex, Debug_Reports);
                        WriteToLog ('*** HAUPTPROGRAMM Str_UTF8 : ' + Str_UTF8, Debug_Reports);

                        UTF8_CharSet := GetUTF8_CharSet(Str_UTF8, Debug_Reports);
                              
                        WriteToLog ('***====================== VOR DEM REPLACE =================================***', Debug_Reports);
                              
                           WriteToLog ('UTF8_CharSet: ' + IntToStr(Math_HextoDec(copy(Str_UTF8, 6, 2))), Debug_Reports);                 
                           // WriteToLog ('UTF8_CharSet: ' + IntToStr(Math_HextoDec(copy(Str_UTF8, 15, 2))), Debug_Reports);                 
                           // WriteToLog ('UTF8_CharSet: ' + IntToStr(Math_HextoDec(copy(Str_UTF8, 24, 2))), Debug_Reports);                 
                           // WriteToLog ('UTF8_CharSet: ' + IntToStr(Math_HextoDec(copy(Str_UTF8, 33, 2))), Debug_Reports);                 
                           WriteToLog ('=======================================================', Debug_Reports);

                        Msg[Intz] := StringReplace(Msg[Intz], Str_UTF7, UTF8_CharSet, [rfIgnoreCase]);
                        WriteToLog ('Str_UTF7: ' + Str_UTF7 + ' gefunden!', Debug_Reports);
                        Ints := Ints + (length (UTF8_CharSet) - 1); // das naechste "+" ab Spalte Ints suchen

                        Break; // Die letzte while-Schleife abbrechen!
                     end; // If Msg[Intz][Intk] = '-' ...
                     Intk := Intk + 1;
                     WriteToLog ('HAUPTPROGRAMM Intk in der letzten While-Schleife : ' + IntToStr(Intk), Debug_Reports);
                  end;  // while
                  Intk := 0;              
               end; // If Msg[Intz][Ints] = '+' ...
               Ints := Ints  + 1;
            end; // While

            // HIER WURDEN DIE PLUSZEICHEN WIEDER EINGEFUEGT!
            // !!!ALLE '*~~~~*' GEGEN "+" AUSTAUSCHEN! DIESE WURDEN OBEN DURCH EIN '*~~~~*' ERSETZT!!!
            // Msg[Intz] := StringReplace(Msg[Intz], '*~~~~*', '+', [rfReplaceAll]);

            // Aenderung 13.10.2021 Austausch "+-" gegen "+"
            Msg[Intz] := StringReplace(Msg[Intz], '+-', '+', [rfReplaceAll]);
            
            If Bool_Box then begin
               WriteToLog ('***HAUPTPROGRAMM: Zeichen in Str_UTF8: ' + IntToStr (Chars_in_Str_UTF8), Debug_Reports);
               WriteToLog ('***HAUPTPROGRAMM: Zeichen in Str_UTF7: ' + IntToStr (Chars_in_Str_UTF7), Debug_Reports);
               WriteToLog ('***HAUPTPROGRAMM: Zeichen in Int_Length_BoxLine: ' + IntToStr (Int_Length_BoxLine), Debug_Reports);
               WriteToLog ('', Debug_Reports);
            	 Box_Line := Box_Line + 1;
            	 Text_Box[Box_Line].Str_UTF7_Chars := Chars_in_Str_UTF7;
            	 Text_Box[Box_Line].Str_UTF8_Chars := Chars_in_Str_UTF8;
            	 Text_Box[Box_Line].Int_Line_Length := Int_Length_BoxLine - Chars_in_Str_UTF7 + Chars_in_Str_UTF8;
            	 If Max_Int_Line_Length < Text_Box[Box_Line].Int_Line_Length then
            	    Max_Int_Line_Length := Text_Box[Box_Line].Int_Line_Length;
               WriteToLog ('***HAUPTPROGRAMM  Int_Line_Length: ' + IntToStr (Text_Box[Box_Line].Int_Line_Length), Debug_Reports);  
            end;   
            Ints := 1;
            Intz := Intz + 1;
         end; // While

         // Die Header "Content-Type:" und "Content-Transfer-Encoding:"
         // werden neu gesetzt!
         Intk := GetHeaderLine ('Content-Type:',Msg);
         Msg := RemoveHeader ('Content-Type:', Msg );
         Msg.insert (Intk, Str_CTH);
         Intk := GetHeaderLine ('Content-Transfer-Encoding:', Msg);
         Msg := RemoveHeader ('Content-Transfer-Encoding:', Msg );
         Msg.insert (Intk, 'Content-Transfer-Encoding: 8bit');
         If GetHeader ('User-Agent:', Msg) <> '' Then begin
            Intk := GetHeaderLine ('User-Agent:',Msg);
            Msg[Intk] := Msg[Intk] + ' UU_Conv/2021-10-24';
         end; // If   

         // ==== Der Subject-Header wird auf uncodierte Zeichen geprueft =====
         // 'Pöbelhaft saß er im Taxi, als jemand vorwitzig flüsterte, Quark käme doch aus Hydranten.'
         
         If Bool_Check_Subj then begin
            Msg := Check_Subjekt_Header (Msg, Debug_Reports);
         end; // If
{         
         If Long_MID = True then begin
         	  Intk := GetHeaderLine ('Message-ID:', Msg);
         	  Str_MID := GetHeader ('Message-ID', Msg);
         	  WriteToLog ('Str_MID : ' + Str_MID, 4);
         	  Long_Mid_Message := StringReplace (Str_MID, '<', '<' + Long_Mid_Message, [rfReplaceAll]);
         	  WriteToLog ('Long_Mid_Message : ' + Long_Mid_Message, 4);
         	  Msg[Intk] := Long_Mid_Message;
         end; // If	  
}         
         // ==== Der Subject-Header wurde auf uncodierte Zeichen geprueft =====

         WriteToLog ('HAUPTPROGRAMM Str_Bin      : ' + Str_Bin, Debug_Reports);
         WriteToLog ('HAUPTPROGRAMM Str_Hex      : ' + Str_Hex, Debug_Reports);
         WriteToLog ('HAUPTPROGRAMM Str_UTF8     : ' + Str_UTF8, Debug_Reports);
         WriteToLog ('HAUPTPROGRAMM UTF8_CharSet : ' + UTF8_CharSet, Debug_Reports)

      end  
      Else begin
         WriteToLog ('HAUPTPROGRAMM: Dieses Posting liegt nicht in UTF7 vor!', Debug_Reports);
         Exit; // Function
      end; // If AnsiPos
   Except
      // Bei Problemen das Senden der Nachricht unterbinden
      begin
         WriteToLog ('FEHLER im Script *** UTF_7_UTF_8_Converter ***' ,5);
         Error_Func := '*** UTF7_UTF8_Converter ***';    
         Result := false;
      end; // Except
   Finally
      // Text_Box.Free;
   end; // Try ... Except ... Finally
End; // Function

//--[ ENDE Function Convert_UTF7_to_UTF8 ]------------------------------------