FLEX-35295 - Switch on Windows Ant Get to download using PowerShell by introducing class PowerShellFileDownloader which using System.Net.WebClient  class and method DownloadFileAsync
diff --git a/flex-installer/ant_on_air/src/org/apache/flex/ant/tags/Get.as b/flex-installer/ant_on_air/src/org/apache/flex/ant/tags/Get.as
index b8d76b6..21709de 100644
--- a/flex-installer/ant_on_air/src/org/apache/flex/ant/tags/Get.as
+++ b/flex-installer/ant_on_air/src/org/apache/flex/ant/tags/Get.as
@@ -31,6 +31,7 @@
     import flash.net.URLLoaderDataFormat;
     import flash.net.URLRequest;
     import flash.net.URLRequestHeader;
+    import flash.system.Capabilities;
     import flash.utils.ByteArray;
     
     import mx.core.IFlexModuleFactory;
@@ -38,7 +39,8 @@
     
     import org.apache.flex.ant.Ant;
     import org.apache.flex.ant.tags.supportClasses.TaskHandler;
-    
+    import org.apache.flex.utils.PowerShellFileDownloader;
+
     [ResourceBundle("ant")]
     [Mixin]
     public class Get extends TaskHandler
@@ -81,7 +83,8 @@
         private var urlLoader:URLLoader;
         
         private var lastProgress:ProgressEvent;
-        
+        private var powerShellFileDownloader:PowerShellFileDownloader;
+
         override public function execute(callbackMode:Boolean, context:Object):Boolean
         {
             super.execute(callbackMode, context);
@@ -97,18 +100,20 @@
             catch (error:Error)
             {
             }
-            
+
+            var destFile:File = getDestFile();
+
             if (skipexisting)
             {
-                var destFile:File = getDestFile();
                 if (destFile.exists)
                     return true;
             }
+
             var s:String = ResourceManager.getInstance().getString('ant', 'GETTING');
             s = s.replace("%1", src);
             ant.output(ant.formatOutput("get", s));
             s = ResourceManager.getInstance().getString('ant', 'GETTO');
-            s = s.replace("%1", getDestFile().nativePath);
+            s = s.replace("%1", destFile.nativePath);
             ant.output(ant.formatOutput("get", s));
             
             var actualSrc:String = src;
@@ -119,14 +124,14 @@
             urlLoader = new URLLoader();
             urlLoader.load(urlRequest);
             urlLoader.dataFormat = URLLoaderDataFormat.BINARY;
-            urlLoader.addEventListener(Event.COMPLETE, completeHandler);
+            urlLoader.addEventListener(Event.COMPLETE, urlLoaderCompleteHandler);
             urlLoader.addEventListener(HTTPStatusEvent.HTTP_RESPONSE_STATUS, statusHandler);
             urlLoader.addEventListener(ProgressEvent.PROGRESS, progressHandler);
             urlLoader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorEventHandler);
             urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
             return false;
         }
-        
+
         private function statusHandler(event:HTTPStatusEvent):void
         {
             if (event.status >= 300 && event.status < 400)
@@ -136,7 +141,7 @@
                 urlLoader.close();
                 
                 // remove handlers from old request
-                urlLoader.removeEventListener(Event.COMPLETE, completeHandler);
+                urlLoader.removeEventListener(Event.COMPLETE, urlLoaderCompleteHandler);
                 urlLoader.removeEventListener(HTTPStatusEvent.HTTP_RESPONSE_STATUS, statusHandler);
                 urlLoader.removeEventListener(ProgressEvent.PROGRESS, progressHandler);
                 urlLoader.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorEventHandler);
@@ -167,24 +172,54 @@
                         newlocation += src.substring(DOWNLOADS_SOURCEFORGE_NET.length);
                     }
                     ant.output(ant.formatOutput("get", "Redirected to: " + newlocation));
-                    var urlRequest:URLRequest = new URLRequest(newlocation);
-                    var refHeader:URLRequestHeader = new URLRequestHeader("Referer", src);
-                    urlRequest.requestHeaders.push(refHeader);
-                    urlRequest.manageCookies = false;
-                    urlRequest.followRedirects = false;
-                    urlRequest.userAgent = "Java";	// required to get sourceforge redirects to do the right thing
-                    urlLoader = new URLLoader();
-                    urlLoader.load(urlRequest);
-                    urlLoader.dataFormat = URLLoaderDataFormat.BINARY;
-                    urlLoader.addEventListener(Event.COMPLETE, completeHandler);
-                    urlLoader.addEventListener(HTTPStatusEvent.HTTP_RESPONSE_STATUS, statusHandler);
-                    urlLoader.addEventListener(ProgressEvent.PROGRESS, progressHandler);
-                    urlLoader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorEventHandler);
-                    urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
+
+                    if (Capabilities.os.indexOf("Win") != -1)
+                    {
+                        var destination:String = getDestFile().nativePath;
+                        powerShellFileDownloader = new PowerShellFileDownloader();
+                        powerShellFileDownloader.addEventListener(ProgressEvent.PROGRESS, progressHandler);
+                        powerShellFileDownloader.addEventListener(Event.COMPLETE, powershellDownloadCompleteHandler);
+                        powerShellFileDownloader.addEventListener(ProgressEvent.STANDARD_ERROR_DATA, standardErrorDataHandler);
+                        powerShellFileDownloader.addEventListener(IOErrorEvent.STANDARD_OUTPUT_IO_ERROR, ioErrorEventHandler);
+                        powerShellFileDownloader.download(newlocation, destination);
+                    }
+                    else
+                    {
+                         var urlRequest:URLRequest = new URLRequest(newlocation);
+                         var refHeader:URLRequestHeader = new URLRequestHeader("Referer", src);
+                         urlRequest.requestHeaders.push(refHeader);
+                         urlRequest.manageCookies = false;
+                         urlRequest.followRedirects = false;
+                         urlRequest.userAgent = "Java";	// required to get sourceforge redirects to do the right thing
+                         urlLoader = new URLLoader();
+                         urlLoader.load(urlRequest);
+                         urlLoader.dataFormat = URLLoaderDataFormat.BINARY;
+                         urlLoader.addEventListener(Event.COMPLETE, urlLoaderCompleteHandler);
+                         urlLoader.addEventListener(HTTPStatusEvent.HTTP_RESPONSE_STATUS, statusHandler);
+                         urlLoader.addEventListener(ProgressEvent.PROGRESS, progressHandler);
+                         urlLoader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorEventHandler);
+                         urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
+                    }
                 }
             }
         }
-        
+
+        private function standardErrorDataHandler(event:ProgressEvent):void
+        {
+            if (lastProgress)
+                ant.output("ioError at: " + lastProgress.bytesLoaded + " of " + lastProgress.bytesTotal);
+
+            ant.output(event.toString());
+            if (!ignoreerrors)
+            {
+                ant.project.failureMessage = ant.formatOutput("get", event.toString());
+                ant.project.status = false;
+            }
+            dispatchEvent(new Event(Event.COMPLETE));
+            event.preventDefault();
+            cleanUpPowerShellFileDownloader();
+        }
+
         private function ioErrorEventHandler(event:IOErrorEvent):void
         {
             if (lastProgress)
@@ -198,7 +233,8 @@
 			}
             dispatchEvent(new Event(Event.COMPLETE));
             event.preventDefault();
-			urlLoader = null;
+            urlLoader = null;
+            cleanUpPowerShellFileDownloader();
         }
         
         private function securityErrorHandler(event:SecurityErrorEvent):void
@@ -221,7 +257,7 @@
             ant.dispatchEvent(event);
         }
         
-        private function completeHandler(event:Event):void
+        private function urlLoaderCompleteHandler(event:Event):void
         {
             var destFile:File = getDestFile();
             if (destFile)
@@ -233,9 +269,28 @@
             }
 
             dispatchEvent(new Event(Event.COMPLETE));
-			urlLoader = null;
+            urlLoader = null;
         }
         
+        private function powershellDownloadCompleteHandler(event:Event):void
+        {
+            ant.output("PowerShell download completed.");
+            dispatchEvent(new Event(Event.COMPLETE));
+            cleanUpPowerShellFileDownloader();
+        }
+
+        private function cleanUpPowerShellFileDownloader():void
+        {
+            if (powerShellFileDownloader)
+            {
+                powerShellFileDownloader.removeEventListener(ProgressEvent.PROGRESS, progressHandler);
+                powerShellFileDownloader.removeEventListener(Event.COMPLETE, powershellDownloadCompleteHandler);
+                powerShellFileDownloader.removeEventListener(ProgressEvent.STANDARD_ERROR_DATA, standardErrorDataHandler);
+                powerShellFileDownloader.removeEventListener(IOErrorEvent.STANDARD_OUTPUT_IO_ERROR, ioErrorEventHandler);
+                powerShellFileDownloader = null;
+            }
+        }
+
         private function getDestFile():File
         {
             try {
diff --git a/flex-installer/ant_on_air/src/org/apache/flex/utils/PowerShellFileDownloader.as b/flex-installer/ant_on_air/src/org/apache/flex/utils/PowerShellFileDownloader.as
new file mode 100644
index 0000000..5f1db51
--- /dev/null
+++ b/flex-installer/ant_on_air/src/org/apache/flex/utils/PowerShellFileDownloader.as
@@ -0,0 +1,145 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.flex.utils
+{
+    import flash.events.IOErrorEvent;
+    
+    import flash.desktop.NativeProcess;
+    import flash.desktop.NativeProcessStartupInfo;
+    import flash.events.Event;
+    import flash.events.EventDispatcher;
+    import flash.events.NativeProcessExitEvent;
+    import flash.events.ProgressEvent;
+    import flash.filesystem.File;
+
+    [Event(name="complete",type="flash.events.Event")]
+    [Event(name="progress",type="flash.events.ProgressEvent")]
+    [Event(name="standardErrorData",type="flash.events.ProgressEvent")]
+    [Event(name="standardOutputIoError",type="flash.events.IOErrorEvent")]
+    public class PowerShellFileDownloader extends EventDispatcher
+    {
+        private var _process:NativeProcess;
+        private var _url:String;
+        private var _downloadDestination:String;
+
+        public function download(url:String, downloadDestination:String):void
+        {
+            cleanUpPowerShellDownloader();
+            
+            _url = url;
+            _downloadDestination = downloadDestination;
+
+            var startupInfo:NativeProcessStartupInfo = getNativeProcessStartupInfoDownload();
+            
+            _process = new NativeProcess();
+            _process.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, onDownloadProgress);
+            _process.addEventListener(ProgressEvent.STANDARD_ERROR_DATA, onDownloadError);
+            _process.addEventListener(IOErrorEvent.STANDARD_OUTPUT_IO_ERROR, onIOError);
+            _process.addEventListener(Event.STANDARD_OUTPUT_CLOSE, onStandardOutputClose);
+            _process.addEventListener(NativeProcessExitEvent.EXIT, onDownloadComplete);
+            _process.start(startupInfo);
+        }
+
+        private function onStandardOutputClose(event:Event):void
+        {
+            dispatchEvent(new Event(Event.COMPLETE));
+            cleanUpPowerShellDownloader();
+        }
+
+        private function onIOError(event:IOErrorEvent):void
+        {
+            dispatchEvent(event.clone());
+            cleanUpPowerShellDownloader();
+        }
+
+        private function onDownloadComplete(event:NativeProcessExitEvent):void
+        {
+            dispatchEvent(new Event(Event.COMPLETE));
+            cleanUpPowerShellDownloader();
+        }
+
+        private function onDownloadError(event:ProgressEvent):void
+        {
+            dispatchEvent(new ProgressEvent(ProgressEvent.STANDARD_ERROR_DATA));
+            cleanUpPowerShellDownloader();
+        }
+
+        private function onDownloadProgress(event:ProgressEvent):void
+        {
+            dispatchEvent(new ProgressEvent(ProgressEvent.PROGRESS, event.bubbles,
+                    event.cancelable, event.bytesLoaded, event.bytesTotal));
+        }
+
+        private function getNativeProcessStartupInfoDownload():NativeProcessStartupInfo
+        {
+            var executable:File = new File("C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe");
+            var startupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo();
+            var arguments:Vector.<String> = new Vector.<String>();
+
+            var command:String = getPowerShellDownloadCommand();
+            arguments.push("-Command");
+            arguments.push(command);
+
+            startupInfo.executable = executable;
+            startupInfo.arguments = arguments;
+
+            return startupInfo;
+        }
+
+        private function getPowerShellDownloadCommand():String
+        {
+            var command:String = "& {";
+            command += "Param([string]$url,[string]$outPath) ";
+            command += "$url = [System.Uri]$url; ";
+            command += "$webClient = New-Object System.Net.WebClient; ";
+            command += "$webClient.DownloadFileAsync($url, $outPath); ";
+            command += "while ($webClient.IsBusy) { Start-Sleep -Milliseconds 10 } ";
+            command += "[Environment]::Exit(0);";
+            command += "}";
+            command += " ";
+            command += "\"";
+            command += _url;
+            command += "\"";
+            command += " ";
+            command += "\"";
+            command += _downloadDestination;
+            command += "\"";
+
+            return command;
+        }
+
+        private function cleanUpPowerShellDownloader():void
+        {
+            if (_process)
+            {
+                _process.closeInput();
+                _process.removeEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, onDownloadProgress);
+                _process.removeEventListener(ProgressEvent.STANDARD_ERROR_DATA, onDownloadError);
+                _process.removeEventListener(IOErrorEvent.STANDARD_OUTPUT_IO_ERROR, onIOError);
+                _process.removeEventListener(Event.STANDARD_OUTPUT_CLOSE, onStandardOutputClose);
+                _process.removeEventListener(NativeProcessExitEvent.EXIT, onDownloadComplete);
+
+                _process = null;
+            }
+
+            _url = null;
+            _downloadDestination = null;
+        }
+    }
+}