public StringCaseMapping(SingleCharCaseMapping singleCharCaseMapping)
 {
     this.CodePointValue         = singleCharCaseMapping.CodePointValue;
     this.UppercaseMappingValue  = singleCharCaseMapping.UppercaseMappingValue;
     this.UppercaseMappingValues = null;
 }
        private static void GenerateUppercaseMappings(StreamWriter writer)
        {
            // NOTE: In order to keep the generated code shorter, we leave out some line breaks in the case statements. This is intentional.

            string      newLine          = writer.NewLine;
            CultureInfo invariantCulture = CultureInfo.InvariantCulture;

            Console.Write("Generating uppercase mappings switch...");

            StringBuilder builder = new StringBuilder(200000);

            #region Preparation
            List <SingleCharCaseMapping> singleCharMappings = new List <SingleCharCaseMapping>(100000);
            List <StringCaseMapping>     stringMappings     = new List <StringCaseMapping>(10000);
            foreach (CodePoint codePoint in CodePoint.CodePoints)
            {
                if (codePoint.Value > 0xFFFF)
                {
                    break;
                }
                CodePoint[] uppercaseMapping = CodePoint.GetUppercaseMapping(codePoint);
                if (uppercaseMapping != null)
                {
                    if (uppercaseMapping.Length == 1)
                    {
                        singleCharMappings.Add(new SingleCharCaseMapping(codePoint.Value, uppercaseMapping[0].Value));
                    }
                    else
                    {
                        System.Diagnostics.Debug.Assert(uppercaseMapping.Length > 1);
                        stringMappings.Add(new StringCaseMapping(codePoint.Value, uppercaseMapping));
                    }
                }
            }

            // Add the special cases for the second halves of surrogate pairs that map to the second halves of other surrogate pairs
            for (uint x = 0xDC28; x <= 0xDC4F; x++)
            {
                singleCharMappings.Add(new SingleCharCaseMapping(x, x - 0x28));
            }
            #endregion             // Preparation

            #region singleCharMappings
            // Sort the single char mappings by the difference first, then by the source code point value
            singleCharMappings.Sort(delegate(SingleCharCaseMapping x, SingleCharCaseMapping y)
            {
                int diff = x.Difference.CompareTo(y.Difference);
                return((diff != 0) ? diff : x.CodePointValue.CompareTo(y.CodePointValue));
            });

            const int CASES_PER_LINE                  = 8;
            int       singleCharMappingsCount         = singleCharMappings.Count;
            int       singleCharMappingsCountMinusOne = singleCharMappingsCount - 1;
            for (int i = 0, casesOnLine = 0; i < singleCharMappingsCount; i++)
            {
                SingleCharCaseMapping singleCharMapping = singleCharMappings[i];
                uint difference       = singleCharMapping.Difference;
                bool isNewLine        = (casesOnLine == 0);
                bool writeCaseBody    = (i == singleCharMappingsCountMinusOne || difference != singleCharMappings[i + 1].Difference);
                bool isLastCaseOnLine = (writeCaseBody || casesOnLine == CASES_PER_LINE - 1);

                // When we only have a single case, we handle it separately
                if (writeCaseBody && (i == 0 || difference != singleCharMappings[i - 1].Difference))
                {
                    stringMappings.Add(new StringCaseMapping(singleCharMapping));
                    continue;
                }

                builder.AppendFormat(invariantCulture, "{0}case 0x{1:X4}:{2}", isNewLine ? "\t" : " ", singleCharMapping.CodePointValue, isLastCaseOnLine ? newLine : null);

                if (writeCaseBody)
                {
                    if ((difference & 0x80000000) == 0)
                    {
                        if (difference == 0x28)
                        {
                            builder.AppendFormat(invariantCulture, "\t\t// The entries for code points 0xDC28 through 0xDC4F (inclusive) are a special case since they are{0}" +
                                                 "\t\t// each the second half of a surrogate pair that maps to the second half of another surrogate pair.{0}" +
                                                 "\t\t// Whether mapping these code points like this is actually correct or not is still to be determined...{0}", newLine);
                        }
                        builder.AppendFormat(invariantCulture, "\t\tx -= 0x{0:X4}; break;{1}", difference, newLine);
                    }
                    else
                    {
                        builder.AppendFormat(invariantCulture, "\t\tx += 0x{0:X4}; break;{1}", singleCharMapping.UppercaseMappingValue - singleCharMapping.CodePointValue, newLine);
                    }
                }

                casesOnLine = isLastCaseOnLine ? 0 : casesOnLine + 1;
            }
            #endregion             // singleCharMappings

            #region stringMappings
            // Sort the string mappings by the number of code point values in the upper case mapping, then by the source code point value
            stringMappings.Sort(delegate(StringCaseMapping x, StringCaseMapping y)
            {
                int diff = (x.UppercaseMappingValues != null ? x.UppercaseMappingValues.Length : 0).CompareTo(
                    y.UppercaseMappingValues != null ? y.UppercaseMappingValues.Length : 0);
                return((diff != 0) ? diff : x.CodePointValue.CompareTo(y.CodePointValue));
            });

            int stringMappingsCount = stringMappings.Count;
            for (int i = 0; i < stringMappingsCount; i++)
            {
                StringCaseMapping stringMapping = stringMappings[i];

                builder.AppendFormat(invariantCulture, "\tcase 0x{0:X4}: return \"", stringMapping.CodePointValue);

                if (stringMapping.UppercaseMappingValues != null)
                {
                    for (int j = 0; j < stringMapping.UppercaseMappingValues.Length; j++)
                    {
                        builder.AppendFormat(invariantCulture, @"\u{0:X4}", stringMapping.UppercaseMappingValues[j]);
                    }
                }
                else
                {
                    builder.AppendFormat(invariantCulture, @"\u{0:X4}", stringMapping.UppercaseMappingValue);
                }

                builder.Append("\";");
                builder.Append(newLine);
            }
            #endregion             // stringMappings

            writer.Write(builder.ToString());
            Console.WriteLine(" Done!");
        }
			public StringCaseMapping(SingleCharCaseMapping singleCharCaseMapping)
			{
				this.CodePointValue = singleCharCaseMapping.CodePointValue;
				this.UppercaseMappingValue = singleCharCaseMapping.UppercaseMappingValue;
				this.UppercaseMappingValues = null;
			}