context: /// <summary>
  /// Copyright (C) 2004-2014 Free Software Foundation, Inc.
  ///
  /// Author: Alexander Gnauck AG-Software, mailto:gnauck@ag-software.de
  ///
  /// This file is part of GNU Libidn.
  ///
  /// GNU Libidn is free software: you can redistribute it and/or
  /// modify it under the terms of either:
  ///
  ///   * the GNU Lesser General Public License as published by the Free
  ///     Software Foundation; either version 3 of the License, or (at
  ///     your option) any later version.
  ///
  /// or
  ///
  ///   * the GNU General Public License as published by the Free
  ///     Software Foundation; either version 2 of the License, or (at
  ///     your option) any later version.
  ///
  /// or both in parallel, as here.
  ///
  /// GNU Libidn is distributed in the hope that it will be useful,
  /// but WITHOUT ANY WARRANTY; without even the implied warranty of
  /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  /// General Public License for more details.
  ///
  /// You should have received copies of the GNU General Public License and
  /// the GNU Lesser General Public License along with this program.  If
  /// not, see <http://www.gnu.org/licenses/>.
  /// </summary>
  
  using System;
  using System.IO;
  using System.Collections;
  using System.Text;
  
  namespace gnu.inet.encoding.misc
  {
      public class GenerateNFKC
      {
          internal static string stripComment(string sIn)
          {
              int c = sIn.IndexOf('#');
              if (c == -1)
              {
                  return sIn;
              }
              else
              {
                  return sIn.Substring(0, (c) - (0));
              }
          }
  
          internal static string[] split(string sIn, char sep)
          {
              StringBuilder sb = new StringBuilder(sIn);
              int c = 0;
              for (int i = 0; i < sb.Length; i++)
              {
                  if (sb[i] == sep)
                  {
                      c++;
                  }
              }
  
              string[] sOut = new string[c + 1];
              c = 0;
              int l = 0;
              for (int i = 0; i < sb.Length; i++)
              {
                  if (sb[i] == sep)
                  {
                      if (l >= i)
                      {
                          sOut[c] = "";
                      }
                      else
                      {
                          // TODO, check this
                          sOut[c] = sb.ToString(l, i-l);
                      }
                      l = i + 1;
                      c++;
                  }
              }
              if (l < sb.Length)
              {
                  sOut[c] = sb.ToString(l, sb.Length - l);
              }
              return sOut;
          }
  
          internal static bool isCompatibilityMapping(string sIn)
          {
              return sIn.Length > 0 && sIn[0] == '<';
          }
  
          internal static string stripCompatibilityTag(string sIn)
          {
              return sIn.Substring(sIn.IndexOf('>') + 2);
          }
  
          internal static string toString(string sIn)
          {
              StringBuilder sOut = new StringBuilder();
              string[] chars = split(sIn, ' ');
              for (int i = 0; i < chars.Length; i++)
              {
                  if (chars[i].Equals("005C"))
                  {
                      sOut.Append("\\\\");
                  }
                  else if (chars[i].Equals("0022"))
                  {
                      sOut.Append("\\\"");
                  }
                  else
                  {
                      sOut.Append("\\u");
                      sOut.Append(chars[i]);
                  }
              }
              return sOut.ToString();
          }
  
          internal static string decompose(string sIn, SortedList mappings)
          {
              StringBuilder sOut = new StringBuilder();
              string[] c = split(sIn, ' ');
  
              for (int i = 0; i < c.Length; i++)
              {
                  if (mappings.ContainsKey(c[i]))
                  {
                      if (sOut.Length > 0)
                      {
                          sOut.Append(" ");
                      }
                      sOut.Append(decompose((string)mappings[c[i]], mappings));
                  }
                  else
                  {
                      if (sOut.Length > 0)
                      {
                          sOut.Append(" ");
                      }
                      sOut.Append(c[i]);
                  }
              }
  
              return sOut.ToString();
          }
  
          public static void Generate()
          {
              // Check if the unicode files exist
              {
                  FileInfo f1 = new FileInfo("CompositionExclusions.txt");
                  FileInfo f2 = new FileInfo("UnicodeData.txt");
                  bool tmpBool;
                  if (File.Exists(f1.FullName))
                      tmpBool = true;
                  else
                      tmpBool = Directory.Exists(f1.FullName);
                  bool tmpBool2;
                  if (File.Exists(f2.FullName))
                      tmpBool2 = true;
                  else
                      tmpBool2 = Directory.Exists(f2.FullName);
                  if (!tmpBool || !tmpBool2)
                  {
                      Console.WriteLine("Unable to find UnicodeData.txt or CompositionExclusions.txt.");
                      Console.WriteLine("Please download the latest version of these file from:");
                      Console.WriteLine("http://www.unicode.org/Public/UNIDATA/");
                      System.Environment.Exit(1);
                  }
              }
  
              ArrayList exclusions = new ArrayList();
              {
                  StreamReader r = new StreamReader("CompositionExclusions.txt", System.Text.Encoding.Default);
                  string line;
                  while (null != (line = r.ReadLine()))
                  {
                      line = stripComment(line);
                      line = line.Trim();
                      if (line.Length == 0)
                      {
                          // Empty line
                      }
                      else if (line.Length == 4)
                      {
                          exclusions.Add(line);
                      }
                      else
                      {
                          // Skip code points > 0xffff
                      }
                  }
                  r.Close();
              }
  
              // Read UnicodeData
  
              SortedList canonical = new SortedList();
              SortedList compatibility = new SortedList();
              SortedList combiningClasses = new SortedList();
              {
                  StreamReader r = new StreamReader("UnicodeData.txt", Encoding.Default);
                  string line;
                  while (null != (line = r.ReadLine()))
                  {
                      line = stripComment(line);
                      line = line.Trim();
  
                      if (line.Length == 0)
                      {
                          // Empty line
                      }
                      else
                      {
                          string[] f = split(line, ';');
  
  
gt:                         if (f[0].Length == 4)