bool WriteFiles()
        {
            if (!Directory.Exists(Options.OutputDir))
            {
                Directory.CreateDirectory(Options.OutputDir);
            }

            foreach (var output in Output.Files)
            {
                var path = output.Key;

                var outputPath = Path.Combine(Options.OutputDir,
                                              Path.GetDirectoryName(path));

                // Make sure the target directory exists.
                Directory.CreateDirectory(outputPath);

                var fullPath = Path.Combine(outputPath, Path.GetFileName(path));

                var outputStream = output.Value;
                outputStream.Position = 0;

                using (var outputFile = File.Create(fullPath))
                    outputStream.CopyTo(outputFile);

                Diagnostics.Message("Generated: {0}", path);
            }

            if (Options.GeneratorKind == GeneratorKind.Java && Options.Compilation.Platform == TargetPlatform.Android)
            {
                Diagnostics.Message("Generating Java stubs...");
                var project = XamarinAndroidBuild.GenerateJavaStubsProject(Assemblies, Options.OutputDir);
                if (!MSBuild(project))
                {
                    return(false);
                }
            }

            return(true);
        }
        bool CreateAar()
        {
            var executableSuffix = Platform.IsWindows ? ".exe" : string.Empty;
            var jar        = Path.Combine(XamarinAndroid.JavaSdkPath, "bin", "jar" + executableSuffix);
            var classesDir = Path.Combine(Options.OutputDir, "classes");
            var androidDir = Path.Combine(Options.OutputDir, "android");
            var name       = Path.GetFileNameWithoutExtension(Project.Assemblies[0]).Replace('-', '_');

            var args = new List <string> {
                "cvf",
                Path.Combine(Options.OutputDir, name + ".aar"),
                $"-C {androidDir} ."
            };

            //Copy libmonosgen-2.0.so and libmonodroid.so
            const string libMonoSgen    = "libmonosgen-2.0.so";
            const string libMonoAndroid = "libmono-android.release.so";

            foreach (var abi in Directory.GetDirectories(XamarinAndroid.LibraryPath))
            {
                var abiDir = Path.Combine(androidDir, "jni", Path.GetFileName(abi));

                string libMonoSgenSourcePath = Path.Combine(abi, libMonoSgen);
                string libMonoSgenDestPath   = Path.Combine(abiDir, libMonoSgen);

                string libMonoAndroidSourcePath = Path.Combine(abi, libMonoAndroid);
                string libMonoAndroidDestPath   = Path.Combine(abiDir, "libmonodroid.so"); //NOTE: Xamarin.Android runtime uses different name from APK

                if (!File.Exists(libMonoSgenSourcePath) || !File.Exists(libMonoAndroidSourcePath))
                {
                    continue;
                }

                if (!Directory.Exists(abiDir))
                {
                    Directory.CreateDirectory(abiDir);
                }
                File.Copy(libMonoSgenSourcePath, libMonoSgenDestPath, true);
                File.Copy(libMonoAndroidSourcePath, libMonoAndroidDestPath, true);
            }

            //Copy JNA native libs
            foreach (var file in Directory.GetFiles(Path.Combine(FindDirectory("external"), "jna"), "android-*"))
            {
                using (var stream = File.OpenRead(file))
                    using (var zip = new ZipArchive(stream))
                    {
                        foreach (var entry in zip.Entries)
                        {
                            //Skip non-*.so files
                            if (!entry.FullName.EndsWith(".so", StringComparison.Ordinal))
                            {
                                continue;
                            }

                            var    arch = Path.GetFileNameWithoutExtension(file);
                            string abi;
                            switch (arch)
                            {
                            case "android-aarch64":
                                abi = "arm64-v8a";
                                break;

                            case "android-arm":
                                abi = "armeabi";
                                break;

                            case "android-armv7":
                                abi = "armeabi-v7a";
                                break;

                            case "android-x86-64":
                                abi = "x86_64";
                                break;

                            default:
                                abi = arch.Replace("android-", string.Empty);
                                break;
                            }

                            var abiDir = Path.Combine(androidDir, "jni", Path.GetFileName(abi));
                            if (!Directory.Exists(abiDir))
                            {
                                Directory.CreateDirectory(abiDir);
                            }

                            using (var zipEntryStream = entry.Open())
                                using (var fileStream = File.Create(Path.Combine(abiDir, entry.Name)))
                                {
                                    zipEntryStream.CopyTo(fileStream);
                                }
                        }
                    }
            }

            //Copy jar to android/classes.jar
            File.Copy(Path.Combine(Options.OutputDir, name + ".jar"), Path.Combine(androidDir, "classes.jar"), true);

            //Copy .NET assemblies
            var assembliesDir = Path.Combine(androidDir, "assets", "assemblies");

            if (!Directory.Exists(assembliesDir))
            {
                Directory.CreateDirectory(assembliesDir);
            }

            foreach (var assembly in Project.Assemblies)
            {
                File.Copy(assembly, Path.Combine(assembliesDir, Path.GetFileName(assembly)), true);
            }

            //Copy any referenced assemblies such as mscorlib.dll
            List <string> referencedAssemblies = new List <string>();

            foreach (var assembly in Assemblies)
            {
                foreach (var reference in assembly.GetReferencedAssemblies())
                {
                    if (!referencedAssemblies.Contains(reference.Name))
                    {
                        referencedAssemblies.Add(reference.Name);
                    }
                }
            }

            Diagnostics.Message("Linking assemblies...");

            //Performs Xamarin.Android build tasks such as Linking, Resource/Asset extraction, invoking aapt.
            var project = XamarinAndroidBuild.GeneratePackageProject(Assemblies, Options.OutputDir, assembliesDir);

            if (!MSBuild(project))
            {
                return(false);
            }

            var invocation = string.Join(" ", args);
            var output     = Invoke(jar, invocation);

            return(output.ExitCode == 0);
        }