public override void Migrate(string sourceFilePath, string destinationFilePath)
        {
            string sourceFileName = Path.GetFileName(sourceFilePath);

            var writingSystemDefinitionV1 = new WritingSystemDefinitionV1();

            new LdmlAdaptorV1().Read(sourceFilePath, writingSystemDefinitionV1);

            string abbreviation = writingSystemDefinitionV1.Abbreviation;
            float  defaultFontSize = writingSystemDefinitionV1.DefaultFontSize;
            string keyboard = writingSystemDefinitionV1.Keyboard;
            string spellCheckingId = writingSystemDefinitionV1.SpellCheckingId;
            string defaultFontName = writingSystemDefinitionV1.DefaultFontName;
            string languageName = writingSystemDefinitionV1.LanguageName.IsOneOf("Unknown Language", "Language Not Listed") ? string.Empty : writingSystemDefinitionV1.LanguageName;
            string variant, privateUse;

            IetfLanguageTag.SplitVariantAndPrivateUse(writingSystemDefinitionV1.Variant, out variant, out privateUse);
            var langTagCleaner = new IetfLanguageTagCleaner(writingSystemDefinitionV1.Language, writingSystemDefinitionV1.Script, writingSystemDefinitionV1.Region,
                                                            variant, privateUse);

            langTagCleaner.Clean();
            string                    langTag           = IetfLanguageTag.Canonicalize(langTagCleaner.GetCompleteTag());
            List <string>             knownKeyboards    = writingSystemDefinitionV1.KnownKeyboards.Select(k => string.IsNullOrEmpty(k.Locale) ? k.Layout : string.Format("{0}_{1}", k.Locale, k.Layout)).ToList();
            bool                      isGraphiteEnabled = false;
            string                    legacyMapping     = string.Empty;
            string                    scriptName        = string.Empty;
            string                    regionName        = string.Empty;
            string                    variantName       = string.Empty;
            SystemCollationDefinition scd = null;

            // Create system collation definition if applicable
            if ((writingSystemDefinitionV1.SortUsing == WritingSystemDefinitionV1.SortRulesType.OtherLanguage) && (!string.IsNullOrEmpty(writingSystemDefinitionV1.SortRules)))
            {
                scd = new SystemCollationDefinition {
                    LanguageTag = writingSystemDefinitionV1.SortRules
                }
            }
            ;

            // Migrate fields from legacy fw namespace, and then remove fw namespace
            XElement ldmlElem = XElement.Load(sourceFilePath);
            XElement fwElem   = ldmlElem.Elements("special").FirstOrDefault(e => !string.IsNullOrEmpty((string)e.Attribute(XNamespace.Xmlns + "fw")));

            if (fwElem != null)
            {
                XElement graphiteEnabledElem = fwElem.Element(FW + "graphiteEnabled");
                if (graphiteEnabledElem != null)
                {
                    if (!bool.TryParse((string)graphiteEnabledElem.Attribute("value"), out isGraphiteEnabled))
                    {
                        isGraphiteEnabled = false;
                    }
                }

                // LegacyMapping
                XElement legacyMappingElem = fwElem.Element(FW + "legacyMapping");
                if (legacyMappingElem != null)
                {
                    legacyMapping = (string)legacyMappingElem.Attribute("value");
                }

                // ScriptName
                XElement scriptNameElem = fwElem.Element(FW + "scriptName");
                if (scriptNameElem != null)
                {
                    scriptName = (string)scriptNameElem.Attribute("value");
                }

                // RegionName
                XElement regionNameElem = fwElem.Element(FW + "regionName");
                if (regionNameElem != null)
                {
                    regionName = (string)regionNameElem.Attribute("value");
                }

                // VariantName
                XElement variantNameElem = fwElem.Element(FW + "variantName");
                if (variantNameElem != null)
                {
                    variantName = (string)variantNameElem.Attribute("value");
                }
            }

            // Record the details for use in PostMigrate where we change the file name to match the ieft language tag where we can.
            var migrationInfo = new LdmlMigrationInfo(sourceFileName)
            {
                LanguageTagBeforeMigration = writingSystemDefinitionV1.Bcp47Tag,
                LanguageTagAfterMigration  = langTag,
                RemovedPropertiesSetter    = ws =>
                {
                    if (!string.IsNullOrEmpty(abbreviation))
                    {
                        ws.Abbreviation = abbreviation;
                    }
                    if (defaultFontSize != 0)
                    {
                        ws.DefaultFontSize = defaultFontSize;
                    }
                    if (!string.IsNullOrEmpty(keyboard))
                    {
                        ws.Keyboard = keyboard;
                    }
                    if (!string.IsNullOrEmpty(spellCheckingId))
                    {
                        ws.SpellCheckingId = spellCheckingId;
                    }
                    if (!string.IsNullOrEmpty(defaultFontName))
                    {
                        ws.DefaultFont = ws.Fonts[defaultFontName];
                    }
                    if (!string.IsNullOrEmpty(languageName))
                    {
                        ws.Language = new LanguageSubtag(ws.Language, languageName);
                    }
                    ws.IsGraphiteEnabled = isGraphiteEnabled;
                    if (!string.IsNullOrEmpty(legacyMapping))
                    {
                        ws.LegacyMapping = legacyMapping;
                    }
                    if (!string.IsNullOrEmpty(scriptName) && ws.Script != null && ws.Script.IsPrivateUse)
                    {
                        ws.Script = new ScriptSubtag(ws.Script, scriptName);
                    }
                    if (!string.IsNullOrEmpty(regionName) && ws.Region != null && ws.Region.IsPrivateUse)
                    {
                        ws.Region = new RegionSubtag(ws.Region, regionName);
                    }
                    if (scd != null)
                    {
                        ws.DefaultCollation = scd;
                    }
                    foreach (string keyboardId in knownKeyboards)
                    {
                        IKeyboardDefinition kd;
                        if (!Keyboard.Controller.TryGetKeyboard(keyboardId, out kd))
                        {
                            kd = Keyboard.Controller.CreateKeyboard(keyboardId, KeyboardFormat.Unknown, Enumerable.Empty <string>());
                        }
                        ws.KnownKeyboards.Add(kd);
                    }
                }
            };

            _migrationInfo.Add(migrationInfo);

            // Store things that stay in ldml but are being moved: WindowsLcid, variantName, font, known keyboards, collations, font features, character sets

            // misc properties
            var staging = new Staging
            {
                WindowsLcid     = writingSystemDefinitionV1.WindowsLcid,
                DefaultFontName = writingSystemDefinitionV1.DefaultFontName,
                SortUsing       = writingSystemDefinitionV1.SortUsing,
                SortRules       = writingSystemDefinitionV1.SortRules,
            };

            // Determine if variantName is non-common private use before preserving it
            if (!string.IsNullOrEmpty(variantName))
            {
                int index = IetfLanguageTag.GetIndexOfFirstNonCommonPrivateUseVariant(IetfLanguageTag.GetVariantSubtags(migrationInfo.LanguageTagAfterMigration));
                if (index > -1)
                {
                    staging.VariantName = variantName;
                }
            }

            if (fwElem != null)
            {
                // DefaultFontFeatures
                XElement fontFeatsElem = fwElem.Element(FW + "defaultFontFeatures");
                if (fontFeatsElem != null && !string.IsNullOrEmpty(staging.DefaultFontName))
                {
                    staging.DefaultFontFeatures = (string)fontFeatsElem.Attribute("value");
                }

                //MatchedPairs, PunctuationPatterns, QuotationMarks deprecated

                // Valid Chars
                XElement validCharsElem = fwElem.Element(FW + "validChars");
                if (validCharsElem != null)
                {
                    try
                    {
                        var fwValidCharsElem = XElement.Parse((string)validCharsElem.Attribute("value"));
                        AddCharacterSet(fwValidCharsElem, staging, "WordForming", "main");
                        AddCharacterSet(fwValidCharsElem, staging, "Numeric", "numeric");
                        AddCharacterSet(fwValidCharsElem, staging, "Other", "punctuation");
                    }
                    catch (XmlException)
                    {
                        ParseLegacyWordformingCharOverridesFile(staging);
                    }
                }
            }

            _staging[sourceFileName] = staging;
        }