/// <summary>
        /// Extract the gradle wrapper and prepare it for use.
        /// </summary>
        /// <param name="logger">Logger to report errors to.</param>
        public bool Extract(Logger logger)
        {
            if (!(EmbeddedResource.ExtractResources(
                      resourceAssembly,
                      new KeyValuePair <string, string>[] {
                new KeyValuePair <string, string>(archiveResource, Archive)
            }, logger) &&
                  PlayServicesResolver.ExtractZip(Archive, archivedFiles, BuildDirectory, true)))
            {
                logger.Log(String.Format("Failed to extract Gradle wrapper resource {0}",
                                         Archive), level: LogLevel.Error);
                return(false);
            }
            var executable = Executable;

            // Files extracted from the zip file don't have the executable bit set on some
            // platforms, so set it here.
            // Unfortunately, File.GetAccessControl() isn't implemented, so we'll use
            // chmod (OSX / Linux) and on Windows extracted files are executable by default
            // so we do nothing.
            if (UnityEngine.RuntimePlatform.WindowsEditor != UnityEngine.Application.platform)
            {
                var result = CommandLine.Run("chmod", String.Format("ug+x \"{0}\"", executable));
                if (result.exitCode != 0)
                {
                    logger.Log(String.Format("Failed to make \"{0}\" executable.\n\n{1}",
                                             executable, result.message),
                               level: LogLevel.Error);
                    return(false);
                }
            }
            return(true);
        }
        /// <summary>
        /// Extract a zip file.
        /// </summary>
        /// <param name="zipFile">File to extract.</param>
        /// <param name="failureMessages">List to add any failure messages to.</param>
        /// <returns>Directory containing unzipped files if successful, null otherwise.</returns>
        private static string ExtractZip(string zipFile, List <string> failureMessages)
        {
            string outputDir = Path.Combine(Path.Combine(Path.GetTempPath(),
                                                         Path.GetRandomFileName()),
                                            Path.GetFileName(zipFile));

            Directory.CreateDirectory(outputDir);
            // This uses reflection to access an internal method for testing purposes.
            // ExtractZip is not part of the public API.
            bool successful = PlayServicesResolver.ExtractZip(zipFile, null, outputDir, false);

            if (!successful)
            {
                failureMessages.Add(String.Format("Unable to extract {0} to {1}",
                                                  zipFile, outputDir));
                Directory.Delete(outputDir, true);
                return(null);
            }
            return(outputDir);
        }