static void Main(string[] args)
        {
            if (args.Length != 3)
            {
                Console.WriteLine("Usage: AssemblyUnhollower.exe SourceAssemblyDir TargetAssemblyDir mscorlib");
                return;
            }

            var sourceDir = args[0];
            var targetDir = args[1];

            Console.WriteLine("Reading assemblies");
            var rewriteContext = new RewriteGlobalContext(args[2], Directory.EnumerateFiles(sourceDir, "*.dll"));

            Console.WriteLine("Creating typedefs");
            Pass10CreateTypedefs.DoPass(rewriteContext);
            Console.WriteLine("Filling typedefs");
            Pass11FillTypedefs.DoPass(rewriteContext);
            Console.WriteLine("Filling generic constraints");
            Pass12FillGenericConstraints.DoPass(rewriteContext);
            Console.WriteLine("Creating members");
            Pass15GenerateMemberContexts.DoPass(rewriteContext);

            Console.WriteLine("Creating static constructors");
            Pass20GenerateStaticConstructors.DoPass(rewriteContext);
            Console.WriteLine("Creating value type fields");
            Pass21GenerateValueTypeFields.DoPass(rewriteContext);
            Console.WriteLine("Creating enums");
            Pass22GenerateEnums.DoPass(rewriteContext);
            Console.WriteLine("Creating IntPtr constructors");
            Pass23GeneratePointerConstructors.DoPass(rewriteContext);
            Console.WriteLine("Creating type getters");
            Pass24GenerateTypeStaticGetters.DoPass(rewriteContext);

            Console.WriteLine("Creating generic method static constructors");
            Pass30GenerateGenericMethodStoreConstructors.DoPass(rewriteContext);
            Console.WriteLine("Creating field accessors");
            Pass40GenerateFieldAccessors.DoPass(rewriteContext);
            Console.WriteLine("Filling methods");
            Pass50GenerateMethods.DoPass(rewriteContext);
            Console.WriteLine("Creating properties");
            Pass70GenerateProperties.DoPass(rewriteContext);

            Console.WriteLine("Writing assemblies");
            Pass99WriteToDisk.DoPass(rewriteContext, targetDir);
        }
        public static void Main(UnhollowerOptions options)
        {
            if (string.IsNullOrEmpty(options.SourceDir))
            {
                Console.WriteLine("No input dir specified; use -h for help");
                return;
            }

            if (string.IsNullOrEmpty(options.OutputDir))
            {
                Console.WriteLine("No target dir specified; use -h for help");
                return;
            }
            if (string.IsNullOrEmpty(options.MscorlibPath))
            {
                Console.WriteLine("No mscorlib specified; use -h for help");
                return;
            }

            if (!Directory.Exists(options.OutputDir))
            {
                Directory.CreateDirectory(options.OutputDir);
            }

            RewriteGlobalContext rewriteContext;

            using (new TimingCookie("Reading assemblies"))
                rewriteContext = new RewriteGlobalContext(options, Directory.EnumerateFiles(options.SourceDir, "*.dll"));

            using (new TimingCookie("Computing renames"))
                Pass05CreateRenameGroups.DoPass(rewriteContext);
            using (new TimingCookie("Creating typedefs"))
                Pass10CreateTypedefs.DoPass(rewriteContext);
            using (new TimingCookie("Computing struct blittability"))
                Pass11ComputeTypeSpecifics.DoPass(rewriteContext);
            using (new TimingCookie("Filling typedefs"))
                Pass12FillTypedefs.DoPass(rewriteContext);
            using (new TimingCookie("Filling generic constraints"))
                Pass13FillGenericConstraints.DoPass(rewriteContext);
            using (new TimingCookie("Creating members"))
                Pass15GenerateMemberContexts.DoPass(rewriteContext);

            using (new TimingCookie("Creating static constructors"))
                Pass20GenerateStaticConstructors.DoPass(rewriteContext);
            using (new TimingCookie("Creating value type fields"))
                Pass21GenerateValueTypeFields.DoPass(rewriteContext);
            using (new TimingCookie("Creating enums"))
                Pass22GenerateEnums.DoPass(rewriteContext);
            using (new TimingCookie("Creating IntPtr constructors"))
                Pass23GeneratePointerConstructors.DoPass(rewriteContext);
            using (new TimingCookie("Creating type getters"))
                Pass24GenerateTypeStaticGetters.DoPass(rewriteContext);
            using (new TimingCookie("Creating non-blittable struct constructors"))
                Pass25GenerateNonBlittableValueTypeDefaultCtors.DoPass(rewriteContext);

            using (new TimingCookie("Creating generic method static constructors"))
                Pass30GenerateGenericMethodStoreConstructors.DoPass(rewriteContext);
            using (new TimingCookie("Creating field accessors"))
                Pass40GenerateFieldAccessors.DoPass(rewriteContext);
            using (new TimingCookie("Filling methods"))
                Pass50GenerateMethods.DoPass(rewriteContext);
            using (new TimingCookie("Generating implicit conversions"))
                Pass60AddImplicitConversions.DoPass(rewriteContext);
            using (new TimingCookie("Creating properties"))
                Pass70GenerateProperties.DoPass(rewriteContext);

            if (options.UnityBaseLibsDir != null)
            {
                using (new TimingCookie("Unstripping types"))
                    Pass79UnstripTypes.DoPass(rewriteContext);
                using (new TimingCookie("Unstripping methods"))
                    Pass80UnstripMethods.DoPass(rewriteContext);
            }
            else
            {
                Console.WriteLine("Not performing unstripping as unity libs are not specified");
            }

            using (new TimingCookie("Writing assemblies"))
                Pass99WriteToDisk.DoPass(rewriteContext, options);

            File.Copy(typeof(IL2CPP).Assembly.Location, Path.Combine(options.OutputDir, typeof(IL2CPP).Assembly.GetName().Name + ".dll"), true);
            File.Copy(typeof(DelegateSupport).Assembly.Location, Path.Combine(options.OutputDir, typeof(DelegateSupport).Assembly.GetName().Name + ".dll"), true);
            File.Copy(typeof(Decoder).Assembly.Location, Path.Combine(options.OutputDir, typeof(Decoder).Assembly.GetName().Name + ".dll"), true);

            Console.WriteLine("Done!");
        }