public bool Load(PrepareCarefully loadout, string presetName)
        {
            SaveRecordPresetV4 preset = new SaveRecordPresetV4();

            Failed = false;
            try {
                Scribe.loader.InitLoading(PresetFiles.FilePathForSavedPreset(presetName));
                preset.ExposeData();

                if (preset.equipment != null)
                {
                    List <EquipmentSelection> equipment = new List <EquipmentSelection>(preset.equipment.Count);
                    foreach (var e in preset.equipment)
                    {
                        ThingDef thingDef = DefDatabase <ThingDef> .GetNamedSilentFail(e.def);

                        if (thingDef == null)
                        {
                            string replacementDefName;
                            if (thingDefReplacements.TryGetValue(e.def, out replacementDefName))
                            {
                                thingDef = DefDatabase <ThingDef> .GetNamedSilentFail(replacementDefName);
                            }
                        }
                        ThingDef stuffDef = null;
                        Gender   gender   = Gender.None;
                        if (!string.IsNullOrEmpty(e.stuffDef))
                        {
                            stuffDef = DefDatabase <ThingDef> .GetNamedSilentFail(e.stuffDef);
                        }
                        if (!string.IsNullOrEmpty(e.gender))
                        {
                            try {
                                gender = (Gender)Enum.Parse(typeof(Gender), e.gender);
                            }
                            catch (Exception) {
                                Log.Warning("Failed to load gender value for animal.");
                                Failed = true;
                                continue;
                            }
                        }
                        if (thingDef != null)
                        {
                            if (string.IsNullOrEmpty(e.stuffDef))
                            {
                                EquipmentKey    key    = new EquipmentKey(thingDef, null, gender);
                                EquipmentRecord record = PrepareCarefully.Instance.EquipmentDatabase.LookupEquipmentRecord(key);
                                if (record != null)
                                {
                                    equipment.Add(new EquipmentSelection(record, e.count));
                                }
                                else
                                {
                                    Log.Warning("Could not find equipment in equipment database: " + key);
                                    Failed = true;
                                    continue;
                                }
                            }
                            else
                            {
                                if (stuffDef != null)
                                {
                                    EquipmentKey    key    = new EquipmentKey(thingDef, stuffDef, gender);
                                    EquipmentRecord record = PrepareCarefully.Instance.EquipmentDatabase.LookupEquipmentRecord(key);
                                    if (record == null)
                                    {
                                        string thing = thingDef != null ? thingDef.defName : "null";
                                        string stuff = stuffDef != null ? stuffDef.defName : "null";
                                        Log.Warning(string.Format("Could not load equipment/resource from the preset.  This may be caused by an invalid thing/stuff combination: " + key));
                                        Failed = true;
                                        continue;
                                    }
                                    else
                                    {
                                        equipment.Add(new EquipmentSelection(record, e.count));
                                    }
                                }
                                else
                                {
                                    Log.Warning("Could not load stuff definition \"" + e.stuffDef + "\" for item \"" + e.def + "\"");
                                    Failed = true;
                                }
                            }
                        }
                        else
                        {
                            Log.Warning("Could not load thing definition \"" + e.def + "\"");
                            Failed = true;
                        }
                    }
                    loadout.Equipment.Clear();
                    foreach (var e in equipment)
                    {
                        loadout.Equipment.Add(e);
                    }
                }
                else
                {
                    Messages.Message("EdB.PC.Dialog.Preset.Error.EquipmentFailed".Translate(), MessageTypeDefOf.ThreatBig);
                    Log.Warning("Failed to load equipment from preset");
                    Failed = true;
                }
            }
            catch (Exception e) {
                Log.Error("Failed to load preset file");
                throw e;
            }
            finally {
                PresetLoader.ClearSaveablesAndCrossRefs();
            }

            List <CustomPawn> allPawns            = new List <CustomPawn>();
            List <CustomPawn> colonistCustomPawns = new List <CustomPawn>();
            List <CustomPawn> hiddenCustomPawns   = new List <CustomPawn>();

            try {
                foreach (SaveRecordPawnV4 p in preset.pawns)
                {
                    CustomPawn pawn = LoadPawn(p);
                    if (pawn != null)
                    {
                        allPawns.Add(pawn);
                        if (!pawn.Hidden)
                        {
                            colonistCustomPawns.Add(pawn);
                        }
                        else
                        {
                            hiddenCustomPawns.Add(pawn);
                        }
                    }
                    else
                    {
                        Messages.Message("EdB.PC.Dialog.Preset.Error.NoCharacter".Translate(), MessageTypeDefOf.ThreatBig);
                        Log.Warning("Preset was created with the following mods: " + preset.mods);
                    }
                }
            }
            catch (Exception e) {
                Messages.Message("EdB.PC.Dialog.Preset.Error.Failed".Translate(), MessageTypeDefOf.ThreatBig);
                Log.Warning(e.ToString());
                Log.Warning("Preset was created with the following mods: " + preset.mods);
                return(false);
            }

            loadout.ClearPawns();
            foreach (CustomPawn p in colonistCustomPawns)
            {
                loadout.AddPawn(p);
            }
            loadout.RelationshipManager.Clear();
            loadout.RelationshipManager.InitializeWithCustomPawns(colonistCustomPawns.AsEnumerable().Concat(hiddenCustomPawns));

            bool atLeastOneRelationshipFailed          = false;
            List <CustomRelationship> allRelationships = new List <CustomRelationship>();

            if (preset.relationships != null)
            {
                try {
                    foreach (SaveRecordRelationshipV3 r in preset.relationships)
                    {
                        if (string.IsNullOrEmpty(r.source) || string.IsNullOrEmpty(r.target) || string.IsNullOrEmpty(r.relation))
                        {
                            atLeastOneRelationshipFailed = true;
                            Log.Warning("Prepare Carefully failed to load a custom relationship from the preset: " + r);
                            continue;
                        }
                        CustomRelationship relationship = LoadRelationship(r, allPawns);
                        if (relationship == null)
                        {
                            atLeastOneRelationshipFailed = true;
                            Log.Warning("Prepare Carefully failed to load a custom relationship from the preset: " + r);
                        }
                        else
                        {
                            allRelationships.Add(relationship);
                        }
                    }
                }
                catch (Exception e) {
                    Messages.Message("EdB.PC.Dialog.Preset.Error.RelationshipFailed".Translate(), MessageTypeDefOf.ThreatBig);
                    Log.Warning(e.ToString());
                    Log.Warning("Preset was created with the following mods: " + preset.mods);
                    return(false);
                }
                if (atLeastOneRelationshipFailed)
                {
                    Messages.Message("EdB.PC.Dialog.Preset.Error.RelationshipFailed".Translate(), MessageTypeDefOf.ThreatBig);
                }
            }
            loadout.RelationshipManager.AddRelationships(allRelationships);

            if (preset.parentChildGroups != null)
            {
                foreach (var groupRecord in preset.parentChildGroups)
                {
                    ParentChildGroup group = new ParentChildGroup();
                    if (groupRecord.parents != null)
                    {
                        foreach (var id in groupRecord.parents)
                        {
                            CustomPawn parent = FindPawnById(id, colonistCustomPawns, hiddenCustomPawns);
                            if (parent != null)
                            {
                                var pawn = parent;
                                if (pawn != null)
                                {
                                    group.Parents.Add(pawn);
                                }
                                else
                                {
                                    Log.Warning("Prepare Carefully could not load a custom parent relationship because it could not find a matching pawn in the relationship manager.");
                                }
                            }
                            else
                            {
                                Log.Warning("Prepare Carefully could not load a custom parent relationship because it could not find a pawn with the saved identifer.");
                            }
                        }
                    }
                    if (groupRecord.children != null)
                    {
                        foreach (var id in groupRecord.children)
                        {
                            CustomPawn child = FindPawnById(id, colonistCustomPawns, hiddenCustomPawns);
                            if (child != null)
                            {
                                var pawn = child;
                                if (pawn != null)
                                {
                                    group.Children.Add(pawn);
                                }
                                else
                                {
                                    Log.Warning("Prepare Carefully could not load a custom child relationship because it could not find a matching pawn in the relationship manager.");
                                }
                            }
                            else
                            {
                                Log.Warning("Prepare Carefully could not load a custom child relationship because it could not find a pawn with the saved identifer.");
                            }
                        }
                    }
                    loadout.RelationshipManager.ParentChildGroups.Add(group);
                }
            }
            loadout.RelationshipManager.ReassignHiddenPawnIndices();

            if (Failed)
            {
                Messages.Message(preset.mods, MessageTypeDefOf.SilentInput);
                Messages.Message("EdB.PC.Dialog.Preset.Error.ThingDefFailed".Translate(), MessageTypeDefOf.ThreatBig);
                Log.Warning("Preset was created with the following mods: " + preset.mods);
                return(false);
            }

            return(true);
        }
        //
        // Static Methods
        //
        public static void SaveToFile(PrepareCarefully data, string presetName)
        {
            bool problem = false;

            try {
                // Verify that all pawns have non-null identifiers.
                foreach (CustomPawn customPawn in data.Pawns)
                {
                    if (customPawn.Id == null)
                    {
                        customPawn.GenerateId();
                    }
                }
                foreach (var g in data.RelationshipManager.ParentChildGroups)
                {
                    foreach (var parent in g.Parents)
                    {
                        if (parent != null && parent.Id == null)
                        {
                            parent.GenerateId();
                        }
                        foreach (var child in g.Children)
                        {
                            if (child != null && child.Id == null)
                            {
                                child.GenerateId();
                            }
                        }
                    }
                }

                SaveRecordPresetV4 preset = new SaveRecordPresetV4();
                preset.mods = GenText.ToCommaList(Enumerable.Select <ModContentPack, string>(LoadedModManager.RunningMods, (Func <ModContentPack, string>)(mod => mod.Name)), true);
                foreach (CustomPawn customPawn in data.Pawns)
                {
                    SaveRecordPawnV4 pawn = new SaveRecordPawnV4(customPawn);
                    preset.pawns.Add(pawn);
                }
                foreach (var g in data.RelationshipManager.ParentChildGroups)
                {
                    foreach (var parent in g.Parents)
                    {
                        if (parent.Hidden)
                        {
                            if (parent.Pawn != null)
                            {
                                SaveRecordPawnV4 pawn = new SaveRecordPawnV4(parent);
                                preset.pawns.Add(pawn);
                            }
                            else
                            {
                                Log.Warning("Prepare Carefully found an empty pawn in a parent child relationship while saving the preset.  Skipping that pawn.");
                            }
                        }
                        foreach (var child in g.Children)
                        {
                            if (child.Hidden)
                            {
                                if (child.Pawn != null)
                                {
                                    SaveRecordPawnV4 pawn = new SaveRecordPawnV4(child);
                                    preset.pawns.Add(pawn);
                                }
                                else
                                {
                                    Log.Warning("Prepare Carefully found an empty pawn in a parent child relationship while saving the preset.  Skipping that pawn.");
                                }
                            }
                        }
                    }
                }
                foreach (var r in data.RelationshipManager.Relationships)
                {
                    if (r.source != null && r.target != null && r.def != null && r.source.Id != null && r.target.Id != null)
                    {
                        SaveRecordRelationshipV3 s = new SaveRecordRelationshipV3(r);
                        preset.relationships.Add(s);
                    }
                    else
                    {
                        problem = true;
                        Log.Warning("Prepare Carefully found an invalid custom relationship when saving a preset: " + presetName);
                        if (r.target != null && r.source != null)
                        {
                            Log.Warning("  Relationship = { source = " + r.source.Id + ", target = " + r.target.Id + ", relationship = " + r.def + "}");
                        }
                        else
                        {
                            Log.Warning("  Relationship = { source = " + r.source + ", target = " + r.target + ", relationship = " + r.def + "}");
                        }
                    }
                }
                foreach (var g in data.RelationshipManager.ParentChildGroups)
                {
                    if (g.Children.Count == 0 || (g.Parents.Count == 0 && g.Children.Count == 1))
                    {
                        continue;
                    }
                    SaveRecordParentChildGroupV3 group = new SaveRecordParentChildGroupV3();
                    group.parents  = new List <string>();
                    group.children = new List <string>();
                    foreach (var p in g.Parents)
                    {
                        if (p.Pawn == null)
                        {
                            problem = true;
                            Log.Warning("Prepare Carefully found an invalid parent/child relationship when saving the preset: " + presetName);
                            continue;
                        }
                        else
                        {
                            group.parents.Add(p.Id);
                        }
                    }
                    foreach (var p in g.Children)
                    {
                        if (p.Pawn == null)
                        {
                            problem = true;
                            Log.Warning("Prepare Carefully found an invalid parent/child relationship when saving the preset: " + presetName);
                            continue;
                        }
                        else
                        {
                            group.children.Add(p.Id);
                        }
                    }
                    preset.parentChildGroups.Add(group);
                }
                foreach (var e in data.Equipment)
                {
                    SaveRecordEquipmentV3 record = new SaveRecordEquipmentV3(e);
                    preset.equipment.Add(record);
                }

                // Start saving.
                Scribe.saver.InitSaving(PresetFiles.FilePathForSavedPreset(presetName), "preset");
                preset.ExposeData();
            }
            catch (Exception e) {
                PrepareCarefully.Instance.State.AddError("EdB.PC.Dialog.Preset.Error.SaveFailed".Translate());
                Log.Error("Failed to save preset file");
                throw e;
            }
            finally {
                Scribe.saver.FinalizeSaving();
                Scribe.mode = LoadSaveMode.Inactive;
                if (problem)
                {
                    PrepareCarefully.Instance.State.AddError("EdB.PC.Dialog.Preset.Error.PartialSaveFailure".Translate());
                }
            }
        }