public static ObjectBinary From(ExportEntry export)
        {
            if (export.IsDefaultObject)
            {
                //DefaultObjects don't have binary
                return(null);
            }
            string className = export.ClassName;

            if (export.IsOrInheritsFrom("BioPawn"))
            {
                //way, waaay too many subclasses of BioPawn to put in the switch statement, so we take care of it here
                className = "BioPawn";
            }
            switch (className)
            {
            case "BioStage":
                return(From <BioStage>(export));

            case "Level":
                return(From <Level>(export));

            case "World":
                return(From <World>(export));

            case "Model":
                return(From <Model>(export));

            case "Polys":
                return(From <Polys>(export));

            case "DecalMaterial":
            case "Material":
                return(From <Material>(export));

            case "MaterialInstanceConstant":
            case "MaterialInstanceTimeVarying":
                if (export.GetProperty <BoolProperty>("bHasStaticPermutationResource")?.Value == true)
                {
                    return(From <MaterialInstance>(export));
                }
                return(Array.Empty <byte>());

            case "FracturedStaticMesh":
                return(From <FracturedStaticMesh>(export));

            case "StaticMesh":
                return(From <StaticMesh>(export));

            case "SkeletalMesh":
                return(From <SkeletalMesh>(export));

            case "CoverMeshComponent":
            case "InteractiveFoliageComponent":
            case "SplineMeshComponent":
            case "FracturedStaticMeshComponent":
            case "StaticMeshComponent":
                return(From <StaticMeshComponent>(export));

            case "DecalComponent":
                return(From <DecalComponent>(export));

            case "Terrain":
                return(From <Terrain>(export));

            case "TerrainComponent":
                return(From <TerrainComponent>(export));

            case "FluidSurfaceComponent":
                return(From <FluidSurfaceComponent>(export));

            case "ModelComponent":
                return(From <ModelComponent>(export));

            case "BioDynamicAnimSet":
                return(From <BioDynamicAnimSet>(export));

            case "BioPawn":
                return(From <BioPawn>(export));

            case "PrefabInstance":
                return(From <PrefabInstance>(export));

            case "Class":
                return(From <UClass>(export));

            case "State":
                return(From <UState>(export));

            case "Function":
                return(From <UFunction>(export));

            case "Enum":
                return(From <UEnum>(export));

            case "Const":
                return(From <UConst>(export));

            case "ScriptStruct":
                return(From <UScriptStruct>(export));

            case "IntProperty":
            case "BoolProperty":
            case "FloatProperty":
            case "NameProperty":
            case "StrProperty":
            case "StringRefProperty":
                return(From <UValueProperty>(export));

            case "ByteProperty":
            case "ObjectProperty":
            case "ComponentProperty":
            case "InterfaceProperty":
            case "ArrayProperty":
            case "StructProperty":
            case "BioMask4Property":
                return(From <UReferenceProperty>(export));

            case "MapProperty":
            case "ClassProperty":
            case "DelegateProperty":
                return(From <UTwoReferenceProperty>(export));

            case "ShaderCache":
                return(From <ShaderCache>(export));

            default:
                return(null);
            }
        }
        //call this method to regenerate ME2ObjectInfo.json
        //Takes a long time (10 minutes maybe?). Application will be completely unresponsive during that time.
        public static void generateInfo()
        {
            var NewClasses         = new Dictionary <string, ClassInfo>();
            var NewStructs         = new Dictionary <string, ClassInfo>();
            var NewEnums           = new Dictionary <string, List <NameReference> >();
            var NewSequenceObjects = new Dictionary <string, SequenceObjectInfo>();

            foreach (string filePath in MELoadedFiles.GetOfficialFiles(MEGame.ME2))
            {
                if (Path.GetExtension(filePath) == ".pcc")
                {
                    using IMEPackage pcc = MEPackageHandler.OpenME2Package(filePath);
                    for (int j = 1; j <= pcc.ExportCount; j++)
                    {
                        ExportEntry exportEntry = pcc.GetUExport(j);
                        string      className   = exportEntry.ClassName;
                        if (className == "Enum")
                        {
                            generateEnumValues(exportEntry, NewEnums);
                        }
                        else if (className == "Class")
                        {
                            string objectName = exportEntry.ObjectName;
                            if (!NewClasses.ContainsKey(objectName))
                            {
                                NewClasses.Add(objectName, generateClassInfo(exportEntry));
                            }
                        }
                        else if (className == "ScriptStruct")
                        {
                            string objectName = exportEntry.ObjectName;
                            if (!NewStructs.ContainsKey(objectName))
                            {
                                NewStructs.Add(objectName, generateClassInfo(exportEntry, isStruct: true));
                            }
                        }
                        else if (exportEntry.IsOrInheritsFrom("SequenceObject"))
                        {
                            if (!NewSequenceObjects.TryGetValue(className, out SequenceObjectInfo seqObjInfo))
                            {
                                seqObjInfo = new SequenceObjectInfo();
                                NewSequenceObjects.Add(className, seqObjInfo);
                            }

                            int objInstanceVersion = exportEntry.GetProperty <IntProperty>("ObjInstanceVersion");
                            if (objInstanceVersion > seqObjInfo.ObjInstanceVersion)
                            {
                                seqObjInfo.ObjInstanceVersion = objInstanceVersion;
                            }
                        }
                    }
                    //Debug.WriteLine("Releasing " + pcc.FileName);
                }
            }

            //CUSTOM ADDITIONS
            try
            {
                NewClasses.Add("LightMapTexture2D", new ClassInfo
                {
                    baseClass   = "Texture2D",
                    exportIndex = 0,
                    pccPath     = UnrealObjectInfo.Me3ExplorerCustomNativeAdditionsName
                });

                NewClasses["StaticMesh"] = new ClassInfo
                {
                    baseClass   = "Object",
                    exportIndex = 0,
                    pccPath     = UnrealObjectInfo.Me3ExplorerCustomNativeAdditionsName,
                    properties  =
                    {
                        new KeyValuePair <string, PropertyInfo>("UseSimpleRigidBodyCollision", new PropertyInfo(PropertyType.BoolProperty)),
                        new KeyValuePair <string, PropertyInfo>("UseSimpleLineCollision",      new PropertyInfo(PropertyType.BoolProperty)),
                        new KeyValuePair <string, PropertyInfo>("UseSimpleBoxCollision",       new PropertyInfo(PropertyType.BoolProperty)),
                        new KeyValuePair <string, PropertyInfo>("UseFullPrecisionUVs",         new PropertyInfo(PropertyType.BoolProperty)),
                        new KeyValuePair <string, PropertyInfo>("BodySetup",                   new PropertyInfo(PropertyType.ObjectProperty, "RB_BodySetup")),
                        new KeyValuePair <string, PropertyInfo>("LODDistanceRatio",            new PropertyInfo(PropertyType.FloatProperty)),
                        new KeyValuePair <string, PropertyInfo>("LightMapCoordinateIndex",     new PropertyInfo(PropertyType.IntProperty)),
                        new KeyValuePair <string, PropertyInfo>("LightMapResolution",          new PropertyInfo(PropertyType.IntProperty)),
                    }
                };
            }
            catch (Exception)
            {
            }

            //SFXPhysicalMaterialDecals missing items
            ClassInfo sfxpmd = NewClasses["SFXPhysicalMaterialDecals"];

            string[] decalComponentArrays = { "HeavyPistol", "AutoPistol", "HandCannon", "SMG", "Shotgun", "HeavyShotgun", "FlakGun", "AssaultRifle", "Needler", "Machinegun", "SniperRifle", "AntiMatRifle", "MassCannon", "ParticleBeam" };
            foreach (string decal in decalComponentArrays)
            {
                sfxpmd.properties.Add(decal, new PropertyInfo(PropertyType.ArrayProperty, "DecalComponent"));
            }

            NewClasses["SFXWeapon"].properties.Add("InstantHitDamageTypes", new PropertyInfo(PropertyType.ArrayProperty, "Class"));

            File.WriteAllText(jsonPath, JsonConvert.SerializeObject(new { SequenceObjects = NewSequenceObjects, Classes = NewClasses, Structs = NewStructs, Enums = NewEnums }, Formatting.Indented));
        }
        //call this method to regenerate ME1ObjectInfo.json
        //Takes a long time (10 to 20 minutes maybe?). Application will be completely unresponsive during that time.
        public static void generateInfo()
        {
            Classes         = new Dictionary <string, ClassInfo>();
            Structs         = new Dictionary <string, ClassInfo>();
            Enums           = new Dictionary <string, List <NameReference> >();
            SequenceObjects = new Dictionary <string, SequenceObjectInfo>();
            foreach (string file in MELoadedFiles.GetOfficialFiles(MEGame.ME1))
            {
                if (Path.GetExtension(file) == ".upk" || Path.GetExtension(file) == ".sfm" || Path.GetExtension(file) == ".u")
                {
                    Debug.WriteLine($"File: {file}");
                    using IMEPackage pcc = MEPackageHandler.OpenME1Package(file);
                    for (int j = 1; j <= pcc.ExportCount; j++)
                    {
                        ExportEntry exportEntry = pcc.GetUExport(j);
                        string      className   = exportEntry.ClassName;
                        if (className == "Enum")
                        {
                            generateEnumValues(exportEntry);
                        }
                        else if (className == "Class")
                        {
                            string objectName = exportEntry.ObjectName;
                            Debug.WriteLine($"Generating information for {objectName}");
                            if (!Classes.ContainsKey(objectName))
                            {
                                Classes.Add(objectName, generateClassInfo(exportEntry));
                            }
                        }
                        else if (className == "ScriptStruct")
                        {
                            string objectName = exportEntry.ObjectName;
                            if (!Structs.ContainsKey(exportEntry.ObjectName))
                            {
                                Structs.Add(objectName, generateClassInfo(exportEntry, isStruct: true));
                            }
                        }
                        else if (exportEntry.IsOrInheritsFrom("SequenceObject"))
                        {
                            if (!SequenceObjects.TryGetValue(className, out SequenceObjectInfo seqObjInfo))
                            {
                                seqObjInfo = new SequenceObjectInfo();
                                SequenceObjects.Add(className, seqObjInfo);
                            }

                            int objInstanceVersion = exportEntry.GetProperty <IntProperty>("ObjInstanceVersion");
                            if (objInstanceVersion > seqObjInfo.ObjInstanceVersion)
                            {
                                seqObjInfo.ObjInstanceVersion = objInstanceVersion;
                            }
                        }
                    }
                }
            }

            //CUSTOM ADDITIONS
            Classes["LightMapTexture2D"] = new ClassInfo
            {
                baseClass   = "Texture2D",
                exportIndex = 0,
                pccPath     = UnrealObjectInfo.Me3ExplorerCustomNativeAdditionsName
            };

            Classes["StaticMesh"] = new ClassInfo
            {
                baseClass   = "Object",
                exportIndex = 0,
                pccPath     = UnrealObjectInfo.Me3ExplorerCustomNativeAdditionsName,
                properties  =
                {
                    new KeyValuePair <string, PropertyInfo>("UseSimpleRigidBodyCollision",   new PropertyInfo(PropertyType.BoolProperty)),
                    new KeyValuePair <string, PropertyInfo>("UseSimpleLineCollision",        new PropertyInfo(PropertyType.BoolProperty)),
                    new KeyValuePair <string, PropertyInfo>("UseSimpleBoxCollision",         new PropertyInfo(PropertyType.BoolProperty)),
                    new KeyValuePair <string, PropertyInfo>("ForceDoubleSidedShadowVolumes", new PropertyInfo(PropertyType.BoolProperty)),
                    new KeyValuePair <string, PropertyInfo>("BodySetup",                     new PropertyInfo(PropertyType.ObjectProperty, "RB_BodySetup")),
                    new KeyValuePair <string, PropertyInfo>("LODDistanceRatio",              new PropertyInfo(PropertyType.FloatProperty)),
                    new KeyValuePair <string, PropertyInfo>("LightMapCoordinateIndex",       new PropertyInfo(PropertyType.IntProperty)),
                    new KeyValuePair <string, PropertyInfo>("LightMapResolution",            new PropertyInfo(PropertyType.IntProperty)),
                    new KeyValuePair <string, PropertyInfo>("SoundCue",                      new PropertyInfo(PropertyType.ObjectProperty, "SoundCue")),
                }
            };


            File.WriteAllText(jsonPath, JsonConvert.SerializeObject(new { SequenceObjects, Classes, Structs, Enums }, Formatting.Indented));
        }