diff --git a/installer/README b/installer/README
index 7a403fd..5a56ba7 100644
--- a/installer/README
+++ b/installer/README
@@ -135,8 +135,8 @@
 
 2.  In the installer directory run: 
         ant get-as3commons.swc
-    This step downloads the required as3commons library and saves it in the libs 
-    directory.
+        ant get-as3httpdclient.swc
+    These step downloads the required libraries and saves it in the libs directory.
 
 3.  If using Adobe Flash Builder, add a linked resource called: 
         APACHE_FLEX_UTILITIES_ROOT 
diff --git a/installer/build.xml b/installer/build.xml
index 24288dc..e052051 100644
--- a/installer/build.xml
+++ b/installer/build.xml
@@ -296,7 +296,20 @@
          -->
     </target>
 
-    <target name="compile" depends="get-as3commons.swc"
+    <target name="check-as3httpclient.swc">
+        <available file="${LIBRARY_DIR}/as3httpclient.swc" property="as3httpclient.swc.present"/>
+    </target>
+
+    <!-- This has a BSD license which is a reciprocal license with the Apache v2 license.  -->
+    <target name="get-as3httpclient.swc" depends="check-as3commons.swc" unless="as3httpclient.swc.present"
+            description="Download as3httpclient.swc">
+        <mkdir dir="${LIBRARY_DIR}"/>
+        <get src="https://github.com/quetwo/as3httpclient/releases/download/1.0/as3httpclient.swc"
+             dest="${LIBRARY_DIR}/as3httpclient.swc"
+             verbose="true"/>
+    </target>
+
+    <target name="compile" depends="get-as3commons.swc, get-as3httpclient.swc"
         description="Compiles the AIR application to a SWF file and places SWF in a temp directory to be packaged.">
         <mxmlc file="${SOURCE_DIR}/${APP_NAME}.${APP_EXTENSION}"
             output="${BUILD_DIR}/${APP_NAME}.swf"
diff --git a/installer/src/InstallApacheFlex.mxml b/installer/src/InstallApacheFlex.mxml
index 0fd98ac..6c91555 100644
--- a/installer/src/InstallApacheFlex.mxml
+++ b/installer/src/InstallApacheFlex.mxml
@@ -51,38 +51,38 @@
         <fx:Component className="CacheDialog" >
             <s:TitleWindow title="Download Cache Configuration" width="400" height="130" 
                            backgroundColor="0xDDDDDD" close="closeUp()">
-                 <fx:Script>
-                     <![CDATA[
-                     import mx.managers.PopUpManager;
-
-                     private function browseFolders():void
-                     {
-                         var file:File;
-                         if (folder.text.length > 0)
-                             file = File.applicationStorageDirectory.resolvePath(folder.text);
-                         else
-                             file = File.applicationStorageDirectory;
-                         file.browseForDirectory("Download Cache Folder");
-                         file.addEventListener(Event.SELECT, folderSelected);
-                     }
-
-                     private function folderSelected(event:Event):void
-                     {
-                         folder.text = event.target.nativePath;
-                     }
-
-                     private function closeUp():void
-                     {
-                         PopUpManager.removePopUp(this);
-                     }
-
-                     private function updateCache():void
-                     {
-                         dispatchEvent(new Event(Event.COMPLETE));
-                         closeUp();
-                     }
-                     ]]>
-                 </fx:Script>
+                <fx:Script>
+                    <![CDATA[
+                        import mx.managers.PopUpManager;
+                        
+                        private function browseFolders():void
+                        {
+                            var file:File;
+                            if (folder.text.length > 0)
+                                file = File.applicationStorageDirectory.resolvePath(folder.text);
+                            else
+                                file = File.applicationStorageDirectory;
+                            file.browseForDirectory("Download Cache Folder");
+                            file.addEventListener(Event.SELECT, folderSelected);
+                        }
+                        
+                        private function folderSelected(event:Event):void
+                        {
+                            folder.text = event.target.nativePath;
+                        }
+                        
+                        private function closeUp():void
+                        {
+                            PopUpManager.removePopUp(this);
+                        }
+                        
+                        private function updateCache():void
+                        {
+                            dispatchEvent(new Event(Event.COMPLETE));
+                            closeUp();
+                        }
+                    ]]>
+                </fx:Script>
                 <s:VGroup left="10" top="10" right="10">
                     <s:CheckBox id="cb" label="Cache Downloaded Files" />
                     <s:HGroup width="100%" verticalAlign="baseline">
@@ -98,3321 +98,3546 @@
             </s:TitleWindow>
         </fx:Component>
     </fx:Declarations>
-     <fx:Script><![CDATA[
-         import flash.globalization.LocaleID;
-         import flash.globalization.StringTools;
+    <fx:Script><![CDATA[
+        import flash.globalization.LocaleID;
+        import flash.globalization.StringTools;
 
-         import mx.collections.ArrayCollection;
-         import mx.core.IFlexDisplayObject;
-         import mx.events.FlexEvent;
-         import mx.events.PropertyChangeEvent;
-         import mx.managers.CursorManager;
-         import mx.managers.PopUpManager;
-         import mx.resources.ResourceBundle;
-         import mx.rpc.events.FaultEvent;
-         import mx.rpc.events.ResultEvent;
-         import mx.rpc.http.HTTPService;
-         import mx.utils.StringUtil;
+        import mx.collections.ArrayCollection;
+        import mx.core.IFlexDisplayObject;
+        import mx.events.FlexEvent;
+        import mx.events.PropertyChangeEvent;
+        import mx.managers.CursorManager;
+        import mx.managers.PopUpManager;
+        import mx.resources.ResourceBundle;
+        import mx.rpc.events.FaultEvent;
+        import mx.rpc.events.ResultEvent;
+        import mx.rpc.http.HTTPService;
+        import mx.utils.StringUtil;
 
-         // This force-links all of the ant task handlers into the Installer.
-         // The Installer doesn't use most of them directly but some script
-         // it runs might.
-         import AntClasses; AntClasses;
-         import org.apache.flex.ant.Ant;
-         import org.apache.flex.packageflexsdk.model.InstallerComponentVO;
-         import org.apache.flex.packageflexsdk.model.OS;
-         import org.apache.flex.packageflexsdk.resource.ViewResourceConstants;
-         import org.apache.flex.packageflexsdk.util.CalcButtonWidth;
-         import org.apache.flex.packageflexsdk.util.MD5CompareUtil;
-         import org.apache.flex.packageflexsdk.view.UpdaterDialog;
-         import org.apache.flex.packageflexsdk.view.components.AdobeLicense;
-         import org.apache.flex.packageflexsdk.view.components.ConsoleWindow;
-         import org.apache.flex.packageflexsdk.view.components.MPLLicense;
-         import org.apache.flex.packageflexsdk.view.events.InstallItemSelectionEvent;
-         import org.apache.flex.utilities.common.Constants;
-         import org.apache.flex.utilities.common.MirrorURLUtil;
-         import org.apache.flex.utilities.common.interfaces.ILog;
-         import org.apache.flex.utilities.common.vo.LogMessagesVO;
-         import org.as3commons.zip.Zip;
-         import org.as3commons.zip.ZipEvent;
-         import org.as3commons.zip.ZipFile;
+        import org.apache.flex.packageflexsdk.util.ApacheURLLoader;
 
-         import spark.events.IndexChangeEvent;
-         import spark.events.TextOperationEvent;
+        import spark.events.IndexChangeEvent;
+        import spark.events.TextOperationEvent;
 
-         import ws.tink.spark.controls.StepItem;
-         import ws.tink.spark.skins.controls.InstallApacheFlexSkin;
+        // This force-links all of the ant task handlers into the Installer.
+        // The Installer doesn't use most of them directly but some script
+        // it runs might.
+        import AntClasses;
 
-         // embed us strings so we can always have them if we can't get to the locale files
-         [Embed(source="properties/en_US.properties", mimeType="application/octet-stream")]
-         private var en_US_Properties:Class;
+        AntClasses;
 
-         private var cleanedUp:Boolean;
+        import org.apache.flex.ant.Ant;
+        import org.apache.flex.ant.tags.Checksum;
+        import org.apache.flex.ant.tags.Copy;
+        import org.apache.flex.ant.tags.Get;
+        import org.apache.flex.packageflexsdk.model.InstallerComponentVO;
+        import org.apache.flex.packageflexsdk.model.OS;
+        import org.apache.flex.packageflexsdk.resource.ViewResourceConstants;
+        import org.apache.flex.packageflexsdk.util.CalcButtonWidth;
+        import org.apache.flex.packageflexsdk.util.MD5CompareUtil;
+        import org.apache.flex.packageflexsdk.view.UpdaterDialog;
+        import org.apache.flex.packageflexsdk.view.components.AdobeLicense;
+        import org.apache.flex.packageflexsdk.view.components.ConsoleWindow;
+        import org.apache.flex.packageflexsdk.view.components.MPLLicense;
+        import org.apache.flex.packageflexsdk.view.events.InstallItemSelectionEvent;
+        import org.apache.flex.utilities.common.Constants;
+        import org.apache.flex.utilities.common.MirrorURLUtil;
+        import org.apache.flex.utilities.common.interfaces.ILog;
+        import org.apache.flex.utilities.common.vo.LogMessagesVO;
+        import org.as3commons.zip.Zip;
+        import org.as3commons.zip.ZipEvent;
+        import org.as3commons.zip.ZipFile;
+        import org.osmf.utils.OSMFStrings;
 
-         private var _mirrorURLCGI:String;
-         private var _useMirror:Boolean = true;
-         private var _latestVersion:String;
-         private var loggedVersion:Boolean;
-         private var logFile:String;
-         private var debugMode:Boolean = false;
-         private var logProgressEvents:Boolean = false;
-         private var showDevBuilds:Boolean = false;
-         private var usingDownloadCache:Boolean;
-         private var downloadCacheFolder:String;
-         private var userDefaultLanguage:String;
-         private var firstTime:Boolean = true;
-         private var legacy:Boolean = true;
-         private var nocache:Boolean = true;
-         private var wasAborted:Boolean;
+        import ws.tink.spark.controls.StepItem;
+        import ws.tink.spark.skins.controls.InstallApacheFlexSkin;
 
-         public var installerAppPath:String;
-         public var installerAppFileName:String;
+        // embed us strings so we can always have them if we can't get to the locale files
+        [Embed(source="properties/en_US.properties", mimeType="application/octet-stream")]
+        private var en_US_Properties:Class;
 
-         // loader needs to be in instance var otherwise it can get GC'd.
-         // We only load one thing at a time, so we can all share this
-         // var
-         private var loader:URLLoader;
+        private var cleanedUp:Boolean;
 
-         /**
-          * Utility Singleton Instances
-          */
-         private var _md5CompareUtil:MD5CompareUtil = MD5CompareUtil.instance;
-         private var _mirrorURLUtil:MirrorURLUtil = MirrorURLUtil.instance;
+        private var _mirrorURLCGI:String;
+        private var _useMirror:Boolean = true;
+        private var _latestVersion:String;
+        private var loggedVersion:Boolean;
+        private var logFile:String;
+        private var debugMode:Boolean = false;
+        private var logProgressEvents:Boolean = false;
+        private var showDevBuilds:Boolean = false;
+        private var usingDownloadCache:Boolean;
+        private var downloadCacheFolder:String;
+        private var userDefaultLanguage:String;
+        private var firstTime:Boolean = true;
+        private var legacy:Boolean = true;
+        private var nocache:Boolean = true;
+        private var wasAborted:Boolean;
+        private var newSDKSelected:Boolean = true;
 
-         /**
-          * Apache Flex binary distribution
-          *
-          * Values stored in sdk-installer-config.xml edit file to change
-          *
-          */
-         private var APACHE_FLEX_BIN_DISTRO_PATH:String;
-         private var APACHE_FLEX_BIN_DISTRO_FILE:String;
-         private var APACHE_FLEX_BIN_INSTALLER_FILE:String;
-         private var APACHE_FLEX_BIN_DISTRO_FILE_SHORT:String;
-         private var APACHE_FLEX_BIN_DISTRO_URL:String;
-         private var APACHE_FLEX_BIN_INSTALLER_URL:String;
-         [Bindable]
-         private var APACHE_FLEX_BIN_DISTRO_VERSION:String = "";
-         [Bindable]
-         private var APACHE_FLEX_BIN_DISTRO_VERSION_DISPLAY:String = "";
+        public var installerAppPath:String;
+        public var installerAppFileName:String;
 
-         /**
-          * Adobe AIR SDK
-          *
-          * Values stored in sdk-installer-config.xml edit file to change
-          *
-          */
-         [Bindable]
-         private var AIR_VERSIONS:ArrayCollection = new ArrayCollection();
-         private var AIR_VERSION:String = "14.0";
-         private var ADOBE_AIR_SDK_WIN_FILE:String;
-         private var ADOBE_AIR_SDK_WIN_URL:String;
-         private var ADOBE_AIR_SDK_MAC_FILE:String;
-         private var ADOBE_AIR_SDK_MAC_URL:String;
-         private var ADOBE_AIR_SDK_LINUX_FILE:String;
-         private var ADOBE_AIR_SDK_LINUX_URL:String;
+        // loader needs to be in instance var otherwise it can get GC'd.
+        // We only load one thing at a time, so we can all share this
+        // var
+        private var loader:ApacheURLLoader;
 
-         /**
-          * Adobe Flash Player
-          *
-          * Values stored in sdk-installer-config.xml edit file to change
-          *
-          */
-         [Bindable]
-         private var FLASH_PLAYER_VERSIONS:ArrayCollection = new ArrayCollection();
-         private var FLASH_PLAYER_VERSION:String = "11.1";
-         private var FLASH_PLAYER_SWF_VERSION:String = "14";
-         private var ADOBE_FB_GLOBALPLAYER_SWC_FILE:String;
-         private var ADOBE_FB_GLOBALPLAYER_SWC_URL:String;
+        /**
+         * Utility Singleton Instances
+         */
+        private var _md5CompareUtil:MD5CompareUtil = MD5CompareUtil.instance;
+        private var _mirrorURLUtil:MirrorURLUtil = MirrorURLUtil.instance;
 
-         /**
-          * Apache Flex
-          *
-          * Values stored in sdk-installer-config.xml edit file to change
-          *
-          */
-         [Bindable]
-         private var FLEX_VERSIONS:ArrayCollection = new ArrayCollection();
+        /**
+         * Apache Flex binary distribution
+         *
+         * Values stored in sdk-installer-config.xml edit file to change
+         *
+         */
+        private var APACHE_FLEX_BIN_DISTRO_PATH:String;
+        private var APACHE_FLEX_BIN_DISTRO_FILE:String;
+        private var APACHE_FLEX_BIN_INSTALLER_FILE:String;
+        private var APACHE_FLEX_BIN_DISTRO_FILE_SHORT:String;
+        private var APACHE_FLEX_BIN_DISTRO_URL:String;
+        private var APACHE_FLEX_BIN_INSTALLER_URL:String;
+        [Bindable]
+        private var APACHE_FLEX_BIN_DISTRO_VERSION:String = "";
+        [Bindable]
+        private var APACHE_FLEX_BIN_DISTRO_VERSION_DISPLAY:String = "";
 
-         /**
-          *
-          * SwfObject
-          *
-          */
-         private var SWF_OBJECT_FILE:String;
-         private var SWF_OBJECT_URL:String;
+        /**
+         * Adobe AIR SDK
+         *
+         * Values stored in sdk-installer-config.xml edit file to change
+         *
+         */
+        [Bindable]
+        private var AIR_VERSIONS:ArrayCollection = new ArrayCollection();
+        private var AIR_VERSION:String = "14.0";
+        private var ADOBE_AIR_SDK_WIN_FILE:String;
+        private var ADOBE_AIR_SDK_WIN_URL:String;
+        private var ADOBE_AIR_SDK_MAC_FILE:String;
+        private var ADOBE_AIR_SDK_MAC_URL:String;
+        private var ADOBE_AIR_SDK_LINUX_FILE:String;
+        private var ADOBE_AIR_SDK_LINUX_URL:String;
 
-         /**
-          * Optional installs
-          *
-          */
-         private var OSMF_SWC_FILE:String;
-         private var OSMF_SWC_URL:String;
-         private var OSMF_SWF_FILE:String = "osmf.swf";
+        /**
+         * Adobe Flash Player
+         *
+         * Values stored in sdk-installer-config.xml edit file to change
+         *
+         */
+        [Bindable]
+        private var FLASH_PLAYER_VERSIONS:ArrayCollection = new ArrayCollection();
+        private var FLASH_PLAYER_VERSION:String = "11.1";
+        private var FLASH_PLAYER_SWF_VERSION:String = "14";
+        private var ADOBE_FB_GLOBALPLAYER_SWC_FILE:String;
+        private var ADOBE_FB_GLOBALPLAYER_SWC_URL:String;
 
-         private var BLAZEDS_FILE:String;
-         private var BLAZEDS_URL:String;
+        /**
+         * Apache Flex
+         *
+         * Values stored in sdk-installer-config.xml edit file to change
+         *
+         */
+        [Bindable]
+        private var FLEX_VERSIONS:ArrayCollection = new ArrayCollection();
 
-         private var AFE_FILE:String;
-         private var AFE_URL:String;
-         private var AGLJ40_FILE:String;
-         private var AGLJ40_URL:String;
-         private var FLEX_FONTKIT_FILE:String;
-         private var FLEX_FONTKIT_URL:String;
-         private var RIDEAU_FILE:String;
-         private var RIDEAU_URL:String;
+        /**
+         *
+         * SwfObject
+         *
+         */
+        private var SWF_OBJECT_FILE:String;
+        private var SWF_OBJECT_URL:String;
 
-         [Bindable]
-         private var _flexHome:String;
-         private var _flexTemp:String;
-         private var _flexHomeDir:File;
-         private var _flexTempDir:File;
-         private var _apacheFlexSDKCompressedFile:File;
-         private var _adobeAIRSDKZipFile:File;
-         private var _fbGlobalPlayerDir:File;
-         private var _fbGlobalPlayerFile:File;
-         private var _blazeDSJarFile:File;
-         private var _afeJarFile:File;
-         private var _aglj40JarFile:File;
-         private var _flexFontKitJarFile:File;
-         private var _rideauJarFile:File;
-         private var _osmfSWCFile:File;
-         private var _osmfSWFFile:File;
+        /**
+         * Optional installs
+         *
+         */
+        private var OSMF_SWC_FILE:String;
+        private var OSMF_SWC_URL:String;
+        private var OSMF_SWF_FILE:String = "osmf.swf";
 
-         private var _os:OS = new OS();
-         private var _loader:URLLoader;
-         private var _process:NativeProcess;
-         private var _previousDisplayedPercent:int = 0;
-         private var _fileUnzipErrorFunction:Function;
-         private var _numOptionalComponents:int = 4;
-         private var _numOptionalComponentsPermissions:int = 0;
-         private var _useOSMF2:Boolean = true;
+        private var BLAZEDS_FILE:String;
+        private var BLAZEDS_URL:String;
 
-         private var languageOverride:String;
-         private var configOverride:String = "";
-         private var stepsOverride:String = "";
-         private var installOverride:String = "";
+        private var AFE_FILE:String;
+        private var AFE_URL:String;
+        private var AGLJ40_FILE:String;
+        private var AGLJ40_URL:String;
+        private var FLEX_FONTKIT_FILE:String;
+        private var FLEX_FONTKIT_URL:String;
+        private var RIDEAU_FILE:String;
+        private var RIDEAU_URL:String;
 
-         private var overlaying:Boolean;
-         private var usingXML:Object;
-         private var additionalProps:Object = {};
-         private var licensePropertyMap:Object = {};
-         private var progressLabels:XML;
-         private var installStepsData:XMLList;
-         private var stepIDs:Vector.<String> = new Vector.<String>();
-         private var stepLabels:Vector.<String> = new Vector.<String>();
-         private var currentStep:int = 0;
+        [Bindable]
+        private var _flexHome:String;
+        private var _flexTemp:String;
+        private var _flexHomeDir:File;
+        private var _flexTempDir:File;
+        private var _apacheFlexSDKCompressedFile:File;
+        private var _adobeAIRSDKZipFile:File;
+        private var _fbGlobalPlayerDir:File;
+        private var _fbGlobalPlayerFile:File;
+        private var _blazeDSJarFile:File;
+        private var _afeJarFile:File;
+        private var _aglj40JarFile:File;
+        private var _flexFontKitJarFile:File;
+        private var _rideauJarFile:File;
+        private var _osmfSWCFile:File;
+        private var _osmfSWFFile:File;
 
-         private var customMenuItem1:ContextMenuItem = new ContextMenuItem("Show Dev Builds");
-         private var customMenuItem2:ContextMenuItem = new ContextMenuItem("Configure Download Cache...");
-         private var customMenuItem3:ContextMenuItem = new ContextMenuItem("Enable Verbose Logging");
-         private var customMenuItem4:ContextMenuItem = new ContextMenuItem("Enable Progress Logging");
+        private var _os:OS = new OS();
+        private var _loader:ApacheURLLoader;
+        private var _process:NativeProcess;
+        private var _previousDisplayedPercent:int = 0;
+        private var _fileUnzipErrorFunction:Function;
+        private var _numOptionalComponents:int = 4;
+        private var _numOptionalComponentsPermissions:int = 0;
+        private var _useOSMF2:Boolean = true;
 
-         [Bindable]
-         private var _viewResourceConstants:ViewResourceConstants;
-         [Bindable]
-         private var supportedLanguages:ArrayCollection = new ArrayCollection();
-         [Bindable]
-         private var _installationSteps:ArrayCollection = new ArrayCollection();
-         [Bindable]
-         private var _installerComponentsDataProvider:ArrayCollection = new ArrayCollection();
-         [Bindable]
-         private var _currentLicenseURL:String;
-         [Bindable]
-         private var _currentLicenseLabel:String;
-         [Bindable]
-         public var _messages:ArrayCollection = new ArrayCollection();
+        private var languageOverride:String;
+        private var configOverride:String = "";
+        private var stepsOverride:String = "";
+        private var installOverride:String = "";
 
-         private var _lastTag:String;
-         private var _lastPublicMessage:String;
-         public function set lastPublicMessage(s:String):void
-         {
-             var tag:String;
-             var c:int;
+        private var overlaying:Boolean;
+        private var usingXML:Object;
+        private var additionalProps:Object = {};
+        private var licensePropertyMap:Object = {};
+        private var progressLabels:XML;
+        private var installStepsData:XMLList;
+        private var compList:XMLList;
+        private var stepIDs:Vector.<String> = new Vector.<String>();
+        private var stepLabels:Vector.<String> = new Vector.<String>();
+        private var currentStep:int = 0;
 
-             c = s.indexOf("[");
-             if (c != -1)
-             {
-                 var c2:int = s.indexOf("] ");
-                 if (c2 != -1)
-                 {
-                     tag = s.substring(c + 1, c2);
-                     s = s.substr(c2 + 2);
-                 }
-             }
-             if (tag && tag == _lastTag && tag == "get")
-                 _lastPublicMessage += "\n" + s;
-             else
-                 _lastPublicMessage = s;
-             _lastTag = tag;
-             dispatchEvent(new Event("messageChanged"));
-         }
+        private var lastLicenseItemSelected:int = 0;
 
-         [Bindable("messageChanged")]
-         public function get lastFilteredPublicMessage():String
-         {
-             return _lastPublicMessage;
-         }
+        private var customMenuItem1:ContextMenuItem = new ContextMenuItem("Show Dev Builds");
+        private var customMenuItem2:ContextMenuItem = new ContextMenuItem("Configure Download Cache...");
+        private var customMenuItem3:ContextMenuItem = new ContextMenuItem("Enable Verbose Logging");
+        private var customMenuItem4:ContextMenuItem = new ContextMenuItem("Enable Progress Logging");
 
-         private function getInvoke():void
-         {
-             var nativeApplication:NativeApplication = NativeApplication.nativeApplication;
-             nativeApplication.addEventListener(InvokeEvent.INVOKE, parseArgs);
-         }
+        [Bindable]
+        private var _viewResourceConstants:ViewResourceConstants;
+        [Bindable]
+        private var supportedLanguages:ArrayCollection = new ArrayCollection();
+        [Bindable]
+        private var _installationSteps:ArrayCollection = new ArrayCollection();
+        [Bindable]
+        private var _installerComponentsDataProvider:ArrayCollection = new ArrayCollection();
+        [Bindable]
+        private var _currentLicenseURL:String;
+        [Bindable]
+        private var _currentLicenseLabel:String;
+        [Bindable]
+        public var _messages:ArrayCollection = new ArrayCollection();
 
-         [Bindable]
-         private var _standardButtonWidth:Number = 88;
+        private var _lastTag:String;
+        private var _lastPublicMessage:String;
+        public function set lastPublicMessage(s:String):void
+        {
+            var tag:String;
+            var c:int;
 
-         public function setButtonWidths():void
-         {
-             var calc:CalcButtonWidth = new CalcButtonWidth(hiddenButton);
+            c = s.indexOf("[");
+            if (c != -1)
+            {
+                var c2:int = s.indexOf("] ");
+                if (c2 != -1)
+                {
+                    tag = s.substring(c + 1, c2);
+                    s = s.substr(c2 + 2);
+                }
+            }
+            if (tag && tag == _lastTag && tag == "get")
+            {
+                _lastPublicMessage += "\n" + s;
+            }
+            else
+            {
+                _lastPublicMessage = s;
+            }
+            _lastTag = tag;
+            dispatchEvent(new Event("messageChanged"));
+        }
 
-             calc.buttonWidth(installLogBtn);
-             calc.buttonWidth(openApacheFlexFolderBtn);
+        [Bindable("messageChanged")]
+        public function get lastFilteredPublicMessage():String
+        {
+            return _lastPublicMessage;
+        }
 
-             _standardButtonWidth = calc.maxButtonWidth([installBtn, browseBtn, closeBtn, nextBtn, firstStepBackBtn, secondStepBackBtn]);
-         }
+        private function getInvoke():void
+        {
+            var nativeApplication:NativeApplication = NativeApplication.nativeApplication;
+            nativeApplication.addEventListener(InvokeEvent.INVOKE, parseArgs);
+        }
 
-         private function parseArgs(event:InvokeEvent):void
-         {
-             for each (var s:String in event.arguments)
-             {
-                 if (s.indexOf("-language=") == 0)
-                 {
-                     languageOverride = s.substring(10);
-                 }
-                 if (s.indexOf("-config=") == 0)
-                 {
-                     configOverride = s.substring(8);
-                 }
-                 if (s.indexOf("-install=") == 0)
-                 {
-                     installOverride = s.substring(9);
-                 }
-                 if (s.indexOf("-steps=") == 0)
-                 {
-                     stepsOverride = s.substring(7);
-                 }
-                 if (s.indexOf("-debug") == 0)
-                 {
-                     debugMode = true;
-                 }
-                 if (s.indexOf("-log=") == 0)
-                 {
-                     debugMode = true;
-                     logFile = s.substring(5);
-                 }
-             }
-             var so:SharedObject = SharedObject.getLocal("InstallApacheFlex");
-             usingDownloadCache = so.data.usingDownloadCache;
-             downloadCacheFolder = so.data.downloadCacheFolder;
-             userDefaultLanguage = so.data.userDefaultLanguage;
-         }
+        [Bindable]
+        private var _standardButtonWidth:Number = 88;
 
-         protected function handleApplicationComplete(event:FlexEvent):void
-         {
-             CursorManager.setBusyCursor();
-             loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, uncaughtErrorHandler);
-             addEventListener(Event.CLOSING, closeApplication);
-             updateWindow();
-             var hasInternet:Boolean = false;
-             var networkAdapters:Vector.<NetworkInterface> = NetworkInfo.networkInfo.findInterfaces();
-             for each (var networkAdapter:NetworkInterface in networkAdapters)
-             {
-                 if (networkAdapter.active)
-                 {
-                     hasInternet = true;
-                     break;
-                 }
-             }
-             if (hasInternet)
-             {
-                 loadXML();
-             }
+        public function setButtonWidths():void
+        {
+            var calc:CalcButtonWidth = new CalcButtonWidth(hiddenButton);
 
-             else
-             {
-                 log("Internet connection unavailable");
-                 abortInstallation("Internet connection unavailable.");
-             }
-             logVersion();
-         }
+            calc.buttonWidth(installLogBtn);
+            calc.buttonWidth(openApacheFlexFolderBtn);
 
-         private function uncaughtErrorHandler(event:UncaughtErrorEvent):void
-         {
-             if (currentStep > 0)
-                 updateActivityStep(stepLabels[currentStep - 1], StepItem.ERROR);
-             if (event.error is Error)
-             {
-                 var error:Error = event.error as Error;
-                 log(error.message);
-                 log(error.getStackTrace(), -1, false);
-                 abortInstallation(error.message + "\n" + error.getStackTrace());
-             }
-             else if (event.error is ErrorEvent)
-             {
-                 var errorEvent:ErrorEvent = event.error as ErrorEvent;
-                 log(errorEvent.text);
-                 abortInstallation(errorEvent.text);
-             }
-             else
-             {
-                 // a non-Error, non-ErrorEvent type was thrown and uncaught
-                 log(event.toString());
-                 abortInstallation(event.toString());
-             }
-         }
+            _standardButtonWidth = calc.maxButtonWidth([installBtn, browseBtn, closeBtn, nextBtn, firstStepBackBtn, secondStepBackBtn]);
+        }
 
-         /**
-          * Define on ResourceManager all keys for translation.
-          * If some key is not present on any other language selected by user, the default value will be displayed
-          * on the screen
-          */
-         private function defineResourceManagerDefaultLanguage():void
-         {
-             selectDefaultLanguage();
-         }
+        private function parseArgs(event:InvokeEvent):void
+        {
+            for each (var s:String in event.arguments)
+            {
+                if (s.indexOf("-language=") == 0)
+                {
+                    languageOverride = s.substring(10);
+                }
+                if (s.indexOf("-config=") == 0)
+                {
+                    configOverride = s.substring(8);
+                }
+                if (s.indexOf("-install=") == 0)
+                {
+                    installOverride = s.substring(9);
+                }
+                if (s.indexOf("-steps=") == 0)
+                {
+                    stepsOverride = s.substring(7);
+                }
+                if (s.indexOf("-debug") == 0)
+                {
+                    debugMode = true;
+                }
+                if (s.indexOf("-log=") == 0)
+                {
+                    debugMode = true;
+                    logFile = s.substring(5);
+                }
+            }
+            var so:SharedObject = SharedObject.getLocal("InstallApacheFlex");
+            usingDownloadCache = so.data.usingDownloadCache;
+            downloadCacheFolder = so.data.downloadCacheFolder;
+            userDefaultLanguage = so.data.userDefaultLanguage;
+        }
 
-         private function getIndexOfEnUS():int
-         {
-             for (var i:int = 0; i < _langSelect.dataProvider.length; i++)
-             {
-                 if (_langSelect.dataProvider.getItemAt(i).data == "en_US")
-                 {
-                     return i;
-                 }
-             }
-             return -1;
-         }
+        protected function handleApplicationComplete(event:FlexEvent):void
+        {
+            CursorManager.setBusyCursor();
+            loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, uncaughtErrorHandler);
+            addEventListener(Event.CLOSING, closeApplication);
+            updateWindow();
+            var hasInternet:Boolean = false;
+            var networkAdapters:Vector.<NetworkInterface> = NetworkInfo.networkInfo.findInterfaces();
+            for each (var networkAdapter:NetworkInterface in networkAdapters)
+            {
+                if (networkAdapter.active)
+                {
+                    hasInternet = true;
+                    break;
+                }
+            }
+            if (hasInternet)
+            {
+                loadXML();
+            }
+            logVersion();
+            if (!hasInternet)
+            {
+                log("Internet connection unavailable");
+                abortInstallation("Internet connection unavailable.");
+            }
+        }
 
-         private function updateWindowTitle():void
-         {
-             if (_viewResourceConstants)
-                 this.nativeWindow.title = StringUtil.substitute(_viewResourceConstants.INFO_WINDOW_TITLE, [APACHE_FLEX_BIN_DISTRO_VERSION_DISPLAY]);
-         }
+        private function uncaughtErrorHandler(event:UncaughtErrorEvent):void
+        {
+            if (currentStep > 0)
+            {
+                updateActivityStep(stepLabels[currentStep - 1], StepItem.ERROR);
+            }
+            if (event.error is Error)
+            {
+                var error:Error = event.error as Error;
+                log(error.message);
+                log(error.getStackTrace(), -1, false);
+                abortInstallation(error.message + "\n" + error.getStackTrace());
+            }
+            else if (event.error is ErrorEvent)
+            {
+                var errorEvent:ErrorEvent = event.error as ErrorEvent;
+                log(errorEvent.text);
+                abortInstallation(errorEvent.text);
+            }
+            else
+            {
+                // a non-Error, non-ErrorEvent type was thrown and uncaught
+                log(event.toString());
+                abortInstallation(event.toString());
+            }
+        }
 
-         protected function selectDefaultLanguageInEmergency():void
-         {
-             loadLanguage("en_US", loadUSInEmergencyComplete);
-         }
+        /**
+         * Define on ResourceManager all keys for translation.
+         * If some key is not present on any other language selected by user, the default value will be displayed
+         * on the screen
+         */
+        private function defineResourceManagerDefaultLanguage():void
+        {
+            selectDefaultLanguage();
+        }
 
-         private function loadUSInEmergencyComplete():void
-         {
-             _viewResourceConstants = ViewResourceConstants.instance;
-             _viewResourceConstants.update();
-         }
+        private function getIndexOfEnUS():int
+        {
+            for (var i:int = 0; i < _langSelect.dataProvider.length; i++)
+            {
+                if (_langSelect.dataProvider.getItemAt(i).data == "en_US")
+                {
+                    return i;
+                }
+            }
+            return -1;
+        }
 
-         protected function selectDefaultLanguage():void
-         {
-             loadLanguage("en_US", loadUSComplete);
-         }
+        private function updateWindowTitle():void
+        {
+            if (_viewResourceConstants)
+            {
+                this.nativeWindow.title = StringUtil.substitute(_viewResourceConstants.INFO_WINDOW_TITLE, [APACHE_FLEX_BIN_DISTRO_VERSION_DISPLAY]);
+            }
+        }
 
-         private function loadUSComplete():void
-         {
-             var userLocale:String;
+        protected function selectDefaultLanguageInEmergency():void
+        {
+            loadLanguage("en_US", loadUSInEmergencyComplete);
+        }
 
-             if (userDefaultLanguage)
-             {
-                 userLocale = userDefaultLanguage;
-             }
-             else
-             {
-                 userLocale = new StringTools(LocaleID.DEFAULT).actualLocaleIDName.replace("-", "_");
-             }
+        private function loadUSInEmergencyComplete():void
+        {
+            _viewResourceConstants = ViewResourceConstants.instance;
+            _viewResourceConstants.update();
+        }
 
-             if (languageOverride)
-             {
-                 userLocale = languageOverride;
-             }
+        protected function selectDefaultLanguage():void
+        {
+            loadLanguage("en_US", loadUSComplete);
+        }
 
-             loadDefaultLanguage(userLocale);
-         }
+        private function loadUSComplete():void
+        {
+            var userLocale:String;
 
-         private function loadDefaultLanguage(userLocale:String):void
-         {
-             loadLanguage(userLocale, defaultLanguageLoaded);
-         }
+            if (userDefaultLanguage)
+            {
+                userLocale = userDefaultLanguage;
+            }
+            else
+            {
+                userLocale = new StringTools(LocaleID.DEFAULT).actualLocaleIDName.replace("-", "_");
+            }
 
-         private var languageURL:String;
-         private var languageID:String;
+            if (languageOverride)
+            {
+                userLocale = languageOverride;
+            }
 
-         private function loadLanguage(userLocale:String, completeFunction:Function):void
-         {
-             if (languageURL && loader) // busy loading another language
-                 loader.close();
+            loadDefaultLanguage(userLocale);
+        }
 
-             if (userLocale == "en_US")
-             {
-                 var ba:ByteArray = new en_US_Properties() as ByteArray;
-                 var data:String = ba.readUTFBytes(ba.bytesAvailable);
-                 installLanguage(userLocale, data);
-                 completeFunction();
-                 return;
-             }
-             var n:int = supportedLanguages.length;
-             for (var i:int = 0; i < n; i++)
-             {
-                 if (supportedLanguages[i].data == userLocale)
-                 {
-                     languageID = userLocale;
-                     languageURL = supportedLanguages[i].path;
-                     var url:URLRequest = new URLRequest(languageURL);
-                     loader = new URLLoader();
-                     loader.dataFormat = URLLoaderDataFormat.TEXT;
-                     loader.addEventListener(IOErrorEvent.IO_ERROR, languageLoadErrorHandler);
-                     loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, languageLoadErrorHandler);
-                     loader.addEventListener(Event.COMPLETE, function (e:Event):void
-                     {
-                         languageURL = null;
-                         installLanguage(userLocale, loader.data);
-                         completeFunction();
-                     });
-                     loader.load(url);
-                     return;
-                 }
-             }
-             completeFunction();
-         }
+        private function loadDefaultLanguage(userLocale:String):void
+        {
+            loadLanguage(userLocale, defaultLanguageLoaded);
+        }
 
-         private function installLanguage(userLocale:String, data:String):void
-         {
-             var resource:ResourceBundle = new ResourceBundle(userLocale, ViewResourceConstants.BUNDLE_NAME);
-             var variables:Array;
-             if (data.indexOf("\r\n") != -1)
-                 variables = data.split("\r\n");
-             else
-                 variables = data.split("\n");
-             for each (var p:String in variables)
-             {
-                 if (p.charAt(0) == "#")
-                     continue;
+        private var languageURL:String;
+        private var languageID:String;
 
-                 var c:int = p.indexOf("=");
-                 if (c != -1)
-                 {
-                     var key:String = p.substr(0, c);
-                     var value:String = p.substr(c + 1);
-                     while (value.indexOf("\\n") != -1)
-                         value = value.replace("\\n", "\n");
-                     resource.content[key] = value;
-                 }
-             }
+        private function loadLanguage(userLocale:String, completeFunction:Function):void
+        {
+            if (languageURL && loader) // busy loading another language
+            {
+                loader.close();
+            }
 
-             resourceManager.addResourceBundle(resource);
-         }
+            if (userLocale == "en_US")
+            {
+                var ba:ByteArray = new en_US_Properties() as ByteArray;
+                var data:String = ba.readUTFBytes(ba.bytesAvailable);
+                installLanguage(userLocale, data);
+                completeFunction();
+                return;
+            }
+            var n:int = supportedLanguages.length;
+            for (var i:int = 0; i < n; i++)
+            {
+                if (supportedLanguages[i].data == userLocale)
+                {
+                    languageID = userLocale;
+                    languageURL = supportedLanguages[i].path;
+                    var url:URLRequest = new URLRequest(languageURL);
+                    loader = new ApacheURLLoader();
+                    loader.dataFormat = URLLoaderDataFormat.TEXT;
+                    loader.addEventListener(IOErrorEvent.IO_ERROR, languageLoadErrorHandler);
+                    loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, languageLoadErrorHandler);
+                    loader.addEventListener(Event.COMPLETE, function (e:Event):void
+                    {
+                        languageURL = null;
+                        installLanguage(userLocale, loader.data);
+                        completeFunction();
+                    });
+                    loader.load(url);
+                    return;
+                }
+            }
+            completeFunction();
+        }
 
-         private function languageLoadErrorHandler(event:Event):void
-         {
-             log("Unable to load language file " + languageURL);
-             log(event.toString());
-             abortInstallation("Unable to load language file " + languageURL);
-         }
+        private function installLanguage(userLocale:String, data:String):void
+        {
+            var resource:ResourceBundle = new ResourceBundle(userLocale, ViewResourceConstants.BUNDLE_NAME);
+            var variables:Array;
+            if (data.indexOf("\r\n") != -1)
+            {
+                variables = data.split("\r\n");
+            }
+            else
+            {
+                variables = data.split("\n");
+            }
+            for each (var p:String in variables)
+            {
+                if (p.charAt(0) == "#")
+                {
+                    continue;
+                }
 
-         private function defaultLanguageLoaded():void
-         {
-             resourceManager.localeChain = [ViewResourceConstants.DEFAULT_LANGUAGE];
+                var c:int = p.indexOf("=");
+                if (c != -1)
+                {
+                    var key:String = p.substr(0, c);
+                    var value:String = p.substr(c + 1);
+                    while (value.indexOf("\\n") != -1)
+                    {
+                        value = value.replace("\\n", "\n");
+                    }
+                    resource.content[key] = value;
+                }
+            }
 
-             var userLocale:String;
+            resourceManager.addResourceBundle(resource);
+        }
 
-             if (userDefaultLanguage)
-             {
-                 userLocale = userDefaultLanguage;
-             }
-             else
-             {
-                 userLocale = new StringTools(LocaleID.DEFAULT).actualLocaleIDName.replace("-", "_");
-             }
+        private function languageLoadErrorHandler(event:Event):void
+        {
+            log("Unable to load language file " + languageURL);
+            log(event.toString());
+            abortInstallation("Unable to load language file " + languageURL);
+        }
 
-             if (languageOverride)
-             {
-                 userLocale = languageOverride;
-             }
-             log("Using Locale: " + userLocale);
+        private function defaultLanguageLoaded():void
+        {
+            resourceManager.localeChain = [ViewResourceConstants.DEFAULT_LANGUAGE];
 
-             var n:int = supportedLanguages.length;
-             for (var i:int = 0; i < n; i++)
-             {
-                 if (supportedLanguages[i].data == userLocale)
-                 {
-                     _langSelect.selectedIndex = i;
+            var userLocale:String;
 
-                     resourceManager.localeChain = [userLocale, "en_US"];
+            if (userDefaultLanguage)
+            {
+                userLocale = userDefaultLanguage;
+            }
+            else
+            {
+                userLocale = new StringTools(LocaleID.DEFAULT).actualLocaleIDName.replace("-", "_");
+            }
 
-                     break;
-                 }
-             }
-             _viewResourceConstants = ViewResourceConstants.instance;
+            if (languageOverride)
+            {
+                userLocale = languageOverride;
+            }
+            log("Using Locale: " + userLocale);
 
-             resourceManager.addEventListener(Event.CHANGE, _viewResourceConstants.update);
+            var n:int = supportedLanguages.length;
+            for (var i:int = 0; i < n; i++)
+            {
+                if (supportedLanguages[i].data == userLocale)
+                {
+                    _langSelect.selectedIndex = i;
 
-             _viewResourceConstants.update();
-             setButtonWidths();
-             directoryBtn.enabled = true;
+                    resourceManager.localeChain = [userLocale, "en_US"];
 
-             updateWindow();
+                    break;
+                }
+            }
+            _viewResourceConstants = ViewResourceConstants.instance;
 
-             _mirrorURLUtil.logMessages = new LogMessagesVO(_viewResourceConstants.FETCH_MIRROR_CGI, _viewResourceConstants.FETCH_MIRROR_CGI_DONE,
-                     _viewResourceConstants.FETCH_MIRROR_CGI_ERROR);
+            resourceManager.addEventListener(Event.CHANGE, _viewResourceConstants.update);
 
-             _mirrorURLUtil.getMirrorURL(Constants.APACHE_FLEX_URL + _mirrorURLCGI, getMirrorURLResultHandler);
-             CursorManager.removeBusyCursor();
+            _viewResourceConstants.update();
+            setButtonWidths();
+            directoryBtn.enabled = true;
 
-             checkValidOS();
-         }
+            updateWindow();
 
-         protected function updateWindow():void
-         {
-             updateWindowTitle();
+            _mirrorURLUtil.logMessages = new LogMessagesVO(_viewResourceConstants.FETCH_MIRROR_CGI, _viewResourceConstants.FETCH_MIRROR_CGI_DONE,
+                    _viewResourceConstants.FETCH_MIRROR_CGI_ERROR);
 
-             this.nativeWindow.x = Screen.mainScreen.bounds.width / 2 - this.nativeWindow.width / 2;
-             this.nativeWindow.y = Screen.mainScreen.bounds.height / 2 - this.nativeWindow.height / 2;
-         }
+            _mirrorURLUtil.getMirrorURL(Constants.APACHE_FLEX_URL + _mirrorURLCGI, getMirrorURLResultHandler);
+            CursorManager.removeBusyCursor();
 
-         protected function loadXML():void
-         {
-             var request:URLRequest;
+            checkValidOS();
+        }
 
-             if (configOverride != "")
-             {
-                 request = new URLRequest(configOverride);
-             }
-             else
-             {
-                 request = new URLRequest(Constants.APACHE_FLEX_URL + Constants.CONFIG_XML_NAME);
-             }
+        protected function updateWindow():void
+        {
+            updateWindowTitle();
 
-             _loader = new URLLoader();
+            this.nativeWindow.x = Screen.mainScreen.bounds.width / 2 - this.nativeWindow.width / 2;
+            this.nativeWindow.y = Screen.mainScreen.bounds.height / 2 - this.nativeWindow.height / 2;
+        }
 
-             try
-             {
-                 _loader.load(request);
-             }
-             catch (error:Error)
-             {
-                 selectDefaultLanguageInEmergency();
-                 log("Unable to load " + Constants.APACHE_FLEX_URL + Constants.CONFIG_XML_NAME);
-                 log(_viewResourceConstants.ERROR_CONFIG_XML_LOAD + error.errorID + " " + error.message);
-                 abortInstallation("Unable to load " + Constants.APACHE_FLEX_URL + Constants.CONFIG_XML_NAME);
-             }
+        protected function loadXML():void
+        {
+            var request:URLRequest;
 
-             _loader.addEventListener(IOErrorEvent.IO_ERROR, xmlError, false, 0, true);
-             _loader.addEventListener(Event.COMPLETE, xmlLoaded, false, 0, true);
-         }
+            if (configOverride != "")
+            {
+                request = new URLRequest(configOverride);
+            }
+            else
+            {
+                request = new URLRequest(Constants.APACHE_FLEX_URL + Constants.CONFIG_XML_NAME);
+                //request = new URLRequest(Constants.CONFIG_XML_NAME);
+            }
 
-         protected function xmlError(event:IOErrorEvent):void
-         {
-             selectDefaultLanguageInEmergency();
-             log("Unable to load " + Constants.APACHE_FLEX_URL + Constants.CONFIG_XML_NAME);
-             log(_viewResourceConstants.ERROR_CONFIG_XML_LOAD + event.errorID);
-             abortInstallation("Unable to load " + Constants.APACHE_FLEX_URL + Constants.CONFIG_XML_NAME + " " + event.toString());
-         }
+            _loader = new ApacheURLLoader();
 
-         protected function xmlLoaded(event:Event):void
-         {
-             if (setXMLVariables())
-             {
-                 _langSelect.dataProvider = supportedLanguages;
-                 _langSelect.selectedIndex = getIndexOfEnUS();
-                 _langSelect.enabled = true;
-                 defineResourceManagerDefaultLanguage();
-             }
-         }
+            try
+            {
+                _loader.load(request);
+            }
+            catch (error:Error)
+            {
+                selectDefaultLanguageInEmergency();
+                log("Unable to load " + Constants.APACHE_FLEX_URL + Constants.CONFIG_XML_NAME);
+                log(_viewResourceConstants.ERROR_CONFIG_XML_LOAD + error.errorID + " " + error.message);
+                abortInstallation("Unable to load " + Constants.APACHE_FLEX_URL + Constants.CONFIG_XML_NAME);
+            }
 
-         protected function checkValidOS():void
-         {
-             if (_os.isOther())
-                 log(_viewResourceConstants.ERROR_UNSUPPORTED_OPERATING_SYSTEM);
-         }
+            _loader.addEventListener(HTTPStatusEvent.HTTP_RESPONSE_STATUS, xmlLoadStatus, false, 0, true);
+            _loader.addEventListener(IOErrorEvent.IO_ERROR, xmlError, false, 0, true);
+            _loader.addEventListener(Event.COMPLETE, xmlLoaded, false, 0, true);
+        }
 
-         private function devBuildFilterFunction(o:Object):Boolean
-         {
-             return !o.devBuild;
-         }
+        protected function xmlLoadStatus(event:HTTPStatusEvent):void
+        {
+            if (event.status >= 400)
+            {
+                log("Unable to load " + Constants.APACHE_FLEX_URL + Constants.CONFIG_XML_NAME);
+                log("\tServer Status: " + event.status);
+            }
+        }
 
-         private function debugModeHandler(event:Event):void
-         {
-             debugMode = true;
-             customMenuItem3.caption = "Verbose Logging Enabled";
-         }
+        protected function xmlError(event:IOErrorEvent):void
+        {
+            selectDefaultLanguageInEmergency();
+            log("Unable to load " + Constants.APACHE_FLEX_URL + Constants.CONFIG_XML_NAME);
+            log(_viewResourceConstants.ERROR_CONFIG_XML_LOAD + event.errorID);
+            abortInstallation("Unable to load " + Constants.APACHE_FLEX_URL + Constants.CONFIG_XML_NAME + " " + event.toString());
+        }
 
-         private function debugProgressHandler(event:Event):void
-         {
-             logProgressEvents = true;
-             customMenuItem4.caption = "Logging Progress Events";
-         }
+        protected function xmlLoaded(event:Event):void
+        {
+            if (setXMLVariables())
+            {
+                _langSelect.dataProvider = supportedLanguages;
+                _langSelect.selectedIndex = getIndexOfEnUS();
+                _langSelect.enabled = true;
+                defineResourceManagerDefaultLanguage();
+            }
+        }
 
-         private function devBuildShowHandler(event:Event):void
-         {
-             var item:Object = flexVersion.selectedItem;
-             FLEX_VERSIONS.filterFunction = null;
-             FLEX_VERSIONS.refresh();
-             flexVersion.selectedItem = item;
-             customMenuItem1.caption = "Showing Dev Builds";
-         }
+        protected function checkValidOS():void
+        {
+            if (_os.isOther())
+            {
+                log(_viewResourceConstants.ERROR_UNSUPPORTED_OPERATING_SYSTEM);
+            }
+        }
 
-         private function downloadCacheHandler(event:Event):void
-         {
-             var dlg:CacheDialog = new CacheDialog();
-             dlg.addEventListener(Event.COMPLETE, updateDownloadCache);
-             PopUpManager.addPopUp(dlg, this, true);
-             PopUpManager.centerPopUp(dlg);
-             dlg.cb.selected = usingDownloadCache;
-             dlg.folder.text = downloadCacheFolder;
-         }
+        private function devBuildFilterFunction(o:Object):Boolean
+        {
+            return !o.devBuild;
+        }
 
-         private function updateDownloadCache(event:Event):void
-         {
-             downloadCacheFolder = event.target.folder.text;
-             usingDownloadCache = event.target.cb.selected;
-             var so:SharedObject = SharedObject.getLocal("InstallApacheFlex");
-             so.data.usingDownloadCache = usingDownloadCache;
-             so.data.downloadCacheFolder = downloadCacheFolder;
-             so.flush();
-         }
+        private function debugModeHandler(event:Event):void
+        {
+            debugMode = true;
+            customMenuItem3.caption = "Verbose Logging Enabled";
+        }
 
-         protected function setXMLVariables():Boolean
-         {
-             try
-             {
-                 var data:XML = XML(_loader.data);
-             }
-             catch (e:Error)
-             {
-                 log("Error parsing configuration file");
-                 abortInstallation("Error parsing configuration file");
-                 return false;
-             }
-             var keepGoing:Boolean = true;
-             if (firstTime)
-             {
-                 firstTime = false;
+        private function debugProgressHandler(event:Event):void
+        {
+            logProgressEvents = true;
+            customMenuItem4.caption = "Logging Progress Events";
+        }
 
-                 _latestVersion = data.version.latest.toString();
+        private function devBuildShowHandler(event:Event):void
+        {
+            var item:Object = flexVersion.selectedItem;
+            FLEX_VERSIONS.filterFunction = null;
+            FLEX_VERSIONS.refresh();
+            flexVersion.selectedItem = item;
+            customMenuItem1.caption = "Showing Dev Builds";
+        }
 
-                 installerAppPath = data.installer.(@name == 'SDKInstallerApp').@path.toString();
-                 installerAppFileName = data.installer.(@name == 'SDKInstallerApp').@file.toString();
+        private function downloadCacheHandler(event:Event):void
+        {
+            var dlg:CacheDialog = new CacheDialog();
+            dlg.addEventListener(Event.COMPLETE, updateDownloadCache);
+            PopUpManager.addPopUp(dlg, this, true);
+            PopUpManager.centerPopUp(dlg);
+            dlg.cb.selected = usingDownloadCache;
+            dlg.folder.text = downloadCacheFolder;
+        }
 
-                 _mirrorURLCGI = data.mirror.(@name == 'MirrorURLCGI').@file.toString();
+        private function updateDownloadCache(event:Event):void
+        {
+            downloadCacheFolder = event.target.folder.text;
+            usingDownloadCache = event.target.cb.selected;
+            var so:SharedObject = SharedObject.getLocal("InstallApacheFlex");
+            so.data.usingDownloadCache = usingDownloadCache;
+            so.data.downloadCacheFolder = downloadCacheFolder;
+            so.flush();
+        }
 
-                 customMenuItem1.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, devBuildShowHandler);
-                 customMenuItem2.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, downloadCacheHandler);
-                 customMenuItem3.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, debugModeHandler);
-                 customMenuItem4.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, debugProgressHandler);
+        protected function setXMLVariables():Boolean
+        {
+            try
+            {
+                var data:XML = XML(_loader.data);
+            }
+            catch (e:Error)
+            {
+                log("Error parsing configuration file");
+                abortInstallation("Error parsing configuration file");
+                return false;
+            }
+            var keepGoing:Boolean = true;
+            if (firstTime)
+            {
+                firstTime = false;
 
-                 var contextMenuCustomItems:Array = ContextMenu(contextMenu).customItems;
-                 contextMenuCustomItems.push(customMenuItem1);
-                 contextMenuCustomItems.push(customMenuItem2);
-                 contextMenuCustomItems.push(customMenuItem3);
-                 contextMenuCustomItems.push(customMenuItem4);
+                _latestVersion = data.version.latest.toString();
 
-                 var name:String;
-                 var versionString:String;
-                 var versionID:String;
+                installerAppPath = data.installer.(@name == 'SDKInstallerApp').@path.toString();
+                installerAppFileName = data.installer.(@name == 'SDKInstallerApp').@file.toString();
 
-                 var languages:XMLList = data.languages.children();
-                 for each (var lang:XML in languages)
-                 {
-                     var item:Object = {
-                         label: lang.@name.toString(),
-                         data: lang.@id.toString(),
-                         path: lang.@path.toString()
-                     };
-                     supportedLanguages.addItem(item);
-                 }
+                _mirrorURLCGI = data.mirror.(@name == 'MirrorURLCGI').@file.toString();
 
-                 var airData:XMLList = data.airsdk[_os.os].versions;
-                 var airVersionList:XMLList = airData[0].children();
-                 var airVersions:Array = [];
-                 var selected:String = airData[0]["@default"].toString();
-                 for each (var airVersion:XML in airVersionList)
-                 {
-                     var displayVersion:String = airVersion.@displayVersion.toString();
-                     versionString = airVersion.@version.toString();
-                     versionID = null;
-                     if (airVersion.@versionID.length() > 0)
-                         versionID = airVersion.@versionID.toString();
-                     airVersions.push(versionString);
-                     var airPath:String = airVersion.path.toString();
-                     var airFile:String = airVersion.file.toString();
-                     AIR_VERSIONS.addItem({
-                         label: "AIR " + displayVersion, version: versionString, versionID: versionID,
-                         path: airPath, file: airFile
-                     });
-                 }
+                customMenuItem1.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, devBuildShowHandler);
+                customMenuItem2.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, downloadCacheHandler);
+                customMenuItem3.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, debugModeHandler);
+                customMenuItem4.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, debugProgressHandler);
 
-                 if (this.airVersion.selectedIndex == -1)
-                 {
-                     this.airVersion.selectedIndex = airVersions.indexOf(selected);
-                 }
+                var contextMenuCustomItems:Array = ContextMenu(contextMenu).customItems;
+                contextMenuCustomItems.push(customMenuItem1);
+                contextMenuCustomItems.push(customMenuItem2);
+                contextMenuCustomItems.push(customMenuItem3);
+                contextMenuCustomItems.push(customMenuItem4);
 
-                 var flexData:XMLList = data.products.children();
-                 var selectedFlexVersion:int;
-                 for each (var productData:XML in flexData)
-                 {
-                     var productName:String = productData.@name.toString();
-                     var productPrefix:String = productData.@prefix.toString();
-                     var productVersionList:XMLList = productData.versions.children();
-                     var isOverlay:Boolean = productData.@overlay.toString() == "true";
-                     var needsAIR:Boolean = productData.@needsAIR.toString() != "false";
-                     var needsFlash:Boolean = productData.@needsFlash.toString() != "false";
-                     var icon:String = productData.@icon.toString();
-                     for each (var productVersion:XML in productVersionList)
-                     {
-                         var shortName:String = productVersion.@file.toString();
-                         var fileName:String = shortName + (_os.isWindows() ? Constants.ARCHIVE_EXTENSION_WIN : Constants.ARCHIVE_EXTENSION_MAC);
-                         versionString = productVersion.@version.toString();
-                         var label:String = productName + " " + versionString;
-                         var ver:String = fileName.substr(productPrefix.length).split("-")[0];
-                         var path:String = productVersion.@path.toString();
-                         var devBuild:Boolean = productVersion.@dev.toString() == "true";
-                         var legacy:Boolean = productVersion.@legacy.toString() == "true";
-                         var nocache:Boolean = productVersion.@nocache.toString() == "true";
-                         if (productVersion["@default"].length() == 1)
-                             selectedFlexVersion = FLEX_VERSIONS.length;
-                         FLEX_VERSIONS.addItem({
-                             shortName: shortName, fileName: fileName, label: label, version: ver,
-                             path: path, overlay: isOverlay, prefix: productPrefix, legacy: legacy, nocache: nocache,
-                             needsAIR: needsAIR, needsFlash: needsFlash, devBuild: devBuild, icon: icon
-                         });
-                     }
-                 }
+                var name:String;
+                var versionString:String;
+                var versionID:String;
 
-                 FLEX_VERSIONS.filterFunction = devBuildFilterFunction;
-                 FLEX_VERSIONS.refresh();
-                 flexVersion.validateNow();
+                var languages:XMLList = data.languages.children();
+                for each (var lang:XML in languages)
+                {
+                    var item:Object = {
+                        label: lang.@name.toString(),
+                        data: lang.@id.toString(),
+                        path: lang.@path.toString()
+                    };
+                    supportedLanguages.addItem(item);
+                }
 
-                 if (this.flexVersion.selectedIndex == -1)
-                 {
-                     this.flexVersion.selectedIndex = selectedFlexVersion;
-                 }
+                var airData:XMLList = data.airsdk[_os.os].versions;
+                var airVersionList:XMLList = airData[0].children();
+                var airVersions:Array = [];
+                var selected:String = airData[0]["@default"].toString();
+                for each (var airVersion:XML in airVersionList)
+                {
+                    var displayVersion:String = airVersion.@displayVersion.toString();
+                    versionString = airVersion.@version.toString();
+                    versionID = null;
+                    if (airVersion.@versionID.length() > 0)
+                    {
+                        versionID = airVersion.@versionID.toString();
+                    }
+                    airVersions.push(versionString);
+                    var airPath:String = airVersion.path.toString();
+                    var airFile:String = airVersion.file.toString();
+                    AIR_VERSIONS.addItem({
+                        label: "AIR " + displayVersion, version: versionString, versionID: versionID,
+                        path: airPath, file: airFile
+                    });
+                }
 
-                 var selectedFlexVersionObject:Object = this.flexVersion.selectedItem;
-                 updateFlexVersionStrings(selectedFlexVersionObject);
+                if (this.airVersion.selectedIndex == -1)
+                {
+                    this.airVersion.selectedIndex = airVersions.indexOf(selected);
+                }
 
-                 if (!APACHE_FLEX_BIN_DISTRO_FILE || !APACHE_FLEX_BIN_DISTRO_PATH)
-                 {
-                     log(_viewResourceConstants.ERROR_INVALID_SDK_URL);
-                     keepGoing = false;
-                 }
+                var flexData:XMLList = data.products.children();
+                var selectedFlexVersion:int;
+                for each (var productData:XML in flexData)
+                {
+                    var productName:String = productData.@name.toString();
+                    var productPrefix:String = productData.@prefix.toString();
+                    var productVersionList:XMLList = productData.versions.children();
+                    var isOverlay:Boolean = productData.@overlay.toString() == "true";
+                    var needsAIR:Boolean = productData.@needsAIR.toString() != "false";
+                    var needsFlash:Boolean = productData.@needsFlash.toString() != "false";
+                    var icon:String = productData.@icon.toString();
+                    for each (var productVersion:XML in productVersionList)
+                    {
+                        var shortName:String = productVersion.@file.toString();
+                        var fileName:String = shortName + (_os.isWindows() ? Constants.ARCHIVE_EXTENSION_WIN : Constants.ARCHIVE_EXTENSION_MAC);
+                        versionString = productVersion.@version.toString();
+                        var label:String = productName + " " + versionString;
+                        var ver:String = fileName.substr(productPrefix.length).split("-")[0];
+                        var path:String = productVersion.@path.toString();
+                        var devBuild:Boolean = productVersion.@dev.toString() == "true";
+                        var legacy:Boolean = productVersion.@legacy.toString() == "true";
+                        var nocache:Boolean = productVersion.@nocache.toString() == "true";
+                        if (productVersion["@default"].length() == 1)
+                        {
+                            selectedFlexVersion = FLEX_VERSIONS.length;
+                        }
+                        FLEX_VERSIONS.addItem({
+                            shortName: shortName, fileName: fileName, label: label, version: ver,
+                            path: path, overlay: isOverlay, prefix: productPrefix, legacy: legacy, nocache: nocache,
+                            needsAIR: needsAIR, needsFlash: needsFlash, devBuild: devBuild, icon: icon
+                        });
+                    }
+                }
 
-                 var flashData:XMLList = data.flashsdk.versions;
-                 var flashVersionList:XMLList = flashData[0].children();
-                 var flashPlayerVersions:Array = [];
-                 selected = flashData[0]["@default"].toString();
-                 for each (var flashVersion:XML in flashVersionList)
-                 {
-                     displayVersion = flashVersion.@displayVersion.toString();
-                     versionString = flashVersion.@version.toString();
-                     versionID = null;
-                     if (flashVersion.@versionID.length() > 0)
-                         versionID = flashVersion.@versionID.toString();
-                     flashPlayerVersions.push(versionString);
-                     if (!_os.isLinux() || Number(versionString) <= 11.2)
-                     {
-                         var swfVersion:String = flashVersion.swfversion.toString();
-                         var flashPath:String = flashVersion.path.toString();
-                         var flashFile:String = flashVersion.file.toString();
-                         FLASH_PLAYER_VERSIONS.addItem({
-                             label: "Flash Player " + displayVersion, version: versionString, swfVersion: swfVersion,
-                             versionID: versionID, path: flashPath, file: flashFile
-                         });
-                     }
-                 }
+                FLEX_VERSIONS.filterFunction = devBuildFilterFunction;
+                FLEX_VERSIONS.refresh();
+                flexVersion.validateNow();
 
-                 if (this.flashPlayerVersion.selectedIndex == -1)
-                 {
-                     this.flashPlayerVersion.selectedIndex = flashPlayerVersions.indexOf(selected);
-                 }
-             }
+                if (this.flexVersion.selectedIndex == -1)
+                {
+                    this.flexVersion.selectedIndex = selectedFlexVersion;
+                }
 
-             ADOBE_AIR_SDK_WIN_FILE = data.airsdk.windows.versions.children().(@version == AIR_VERSION).file.toString();
-             ADOBE_AIR_SDK_WIN_URL = data.airsdk.windows.versions.children().(@version == AIR_VERSION).path.toString();
-             if (_os.isWindows() && (!ADOBE_AIR_SDK_WIN_FILE || !ADOBE_AIR_SDK_WIN_URL))
-             {
-                 log(_viewResourceConstants.ERROR_INVALID_AIR_SDK_URL_WINDOWS);
-                 keepGoing = false;
-             }
-             ADOBE_AIR_SDK_WIN_URL += ADOBE_AIR_SDK_WIN_FILE;
+                var selectedFlexVersionObject:Object = this.flexVersion.selectedItem;
+                updateFlexVersionStrings(selectedFlexVersionObject);
 
-             ADOBE_AIR_SDK_MAC_FILE = data.airsdk.mac.versions.children().(@version == AIR_VERSION).file.toString();
-             ADOBE_AIR_SDK_MAC_URL = data.airsdk.mac.versions.children().(@version == AIR_VERSION).path.toString();
-             if (_os.isMac() && (!ADOBE_AIR_SDK_MAC_FILE || !ADOBE_AIR_SDK_MAC_URL))
-             {
-                 log(_viewResourceConstants.ERROR_INVALID_AIR_SDK_URL_MAC);
-                 keepGoing = false;
-             }
-             ADOBE_AIR_SDK_MAC_URL += ADOBE_AIR_SDK_MAC_FILE;
+                if (!APACHE_FLEX_BIN_DISTRO_FILE || !APACHE_FLEX_BIN_DISTRO_PATH)
+                {
+                    log(_viewResourceConstants.ERROR_INVALID_SDK_URL);
+                    keepGoing = false;
+                }
 
-             ADOBE_AIR_SDK_LINUX_FILE = data.airsdk.linux.versions.children().(@version == AIR_VERSION).file.toString();
-             ADOBE_AIR_SDK_LINUX_URL = data.airsdk.linux.versions.children().(@version == AIR_VERSION).path.toString();
-             if (_os.isLinux() && (!ADOBE_AIR_SDK_LINUX_FILE || !ADOBE_AIR_SDK_LINUX_URL))
-             {
-                 log(_viewResourceConstants.ERROR_INVALID_AIR_SDK_URL_LINUX);
-                 keepGoing = false;
-             }
-             ADOBE_AIR_SDK_LINUX_URL += ADOBE_AIR_SDK_LINUX_FILE;
+                var flashData:XMLList = data.flashsdk.versions;
+                var flashVersionList:XMLList = flashData[0].children();
+                var flashPlayerVersions:Array = [];
+                selected = flashData[0]["@default"].toString();
+                for each (var flashVersion:XML in flashVersionList)
+                {
+                    displayVersion = flashVersion.@displayVersion.toString();
+                    versionString = flashVersion.@version.toString();
+                    versionID = null;
+                    if (flashVersion.@versionID.length() > 0)
+                    {
+                        versionID = flashVersion.@versionID.toString();
+                    }
+                    flashPlayerVersions.push(versionString);
+                    if (!_os.isLinux() || Number(versionString) <= 11.2)
+                    {
+                        var swfVersion:String = flashVersion.swfversion.toString();
+                        var flashPath:String = flashVersion.path.toString();
+                        var flashFile:String = flashVersion.file.toString();
+                        FLASH_PLAYER_VERSIONS.addItem({
+                            label: "Flash Player " + displayVersion, version: versionString, swfVersion: swfVersion,
+                            versionID: versionID, path: flashPath, file: flashFile
+                        });
+                    }
+                }
 
-             ADOBE_FB_GLOBALPLAYER_SWC_FILE = data.flashsdk.versions.children().(@version == FLASH_PLAYER_VERSION).file.toString();
-             ADOBE_FB_GLOBALPLAYER_SWC_URL = data.flashsdk.versions.children().(@version == FLASH_PLAYER_VERSION).path.toString();
-             FLASH_PLAYER_SWF_VERSION = data.flashsdk.versions.children().(@version == FLASH_PLAYER_VERSION).swfversion.toString();
-             if (!ADOBE_FB_GLOBALPLAYER_SWC_FILE || !ADOBE_FB_GLOBALPLAYER_SWC_URL)
-             {
-                 log(_viewResourceConstants.ERROR_INVALID_FLASH_PLAYER_SWC_URL);
-                 keepGoing = false;
-             }
-             ADOBE_FB_GLOBALPLAYER_SWC_URL += ADOBE_FB_GLOBALPLAYER_SWC_FILE;
+                if (this.flashPlayerVersion.selectedIndex == -1)
+                {
+                    this.flashPlayerVersion.selectedIndex = flashPlayerVersions.indexOf(selected);
+                }
+            }
 
-             SWF_OBJECT_FILE = data.swfobject.@file.toString();
-             SWF_OBJECT_URL = data.swfobject.@path.toString();
+            ADOBE_AIR_SDK_WIN_FILE = data.airsdk.windows.versions.children().(@version == AIR_VERSION).file.toString();
+            ADOBE_AIR_SDK_WIN_URL = data.airsdk.windows.versions.children().(@version == AIR_VERSION).path.toString();
+            if (_os.isWindows() && (!ADOBE_AIR_SDK_WIN_FILE || !ADOBE_AIR_SDK_WIN_URL))
+            {
+                log(_viewResourceConstants.ERROR_INVALID_AIR_SDK_URL_WINDOWS);
+                keepGoing = false;
+            }
+            ADOBE_AIR_SDK_WIN_URL += ADOBE_AIR_SDK_WIN_FILE;
 
-             //Supporting OSMF 2.0 from 4.11 onwards.  
-             if (APACHE_FLEX_BIN_DISTRO_VERSION == "4.9.1" || APACHE_FLEX_BIN_DISTRO_VERSION == "4.10.0")
-             {
-                 OSMF_SWC_FILE = data.OSMF_SWC.@file.toString();
-                 OSMF_SWC_URL = data.OSMF_SWC.@path.toString();
-                 _useOSMF2 = false;
-             }
-             else
-             {
-                 OSMF_SWC_FILE = data["OSMF_SWC_2.0"].@file.toString();
-                 OSMF_SWC_URL = data["OSMF_SWC_2.0"].@path.toString();
-                 _useOSMF2 = true;
-             }
+            ADOBE_AIR_SDK_MAC_FILE = data.airsdk.mac.versions.children().(@version == AIR_VERSION).file.toString();
+            ADOBE_AIR_SDK_MAC_URL = data.airsdk.mac.versions.children().(@version == AIR_VERSION).path.toString();
+            if (_os.isMac() && (!ADOBE_AIR_SDK_MAC_FILE || !ADOBE_AIR_SDK_MAC_URL))
+            {
+                log(_viewResourceConstants.ERROR_INVALID_AIR_SDK_URL_MAC);
+                keepGoing = false;
+            }
+            ADOBE_AIR_SDK_MAC_URL += ADOBE_AIR_SDK_MAC_FILE;
 
-             BLAZEDS_FILE = data.BlazeDS.@file.toString();
-             BLAZEDS_URL = data.BlazeDS.@path.toString();
+            ADOBE_AIR_SDK_LINUX_FILE = data.airsdk.linux.versions.children().(@version == AIR_VERSION).file.toString();
+            ADOBE_AIR_SDK_LINUX_URL = data.airsdk.linux.versions.children().(@version == AIR_VERSION).path.toString();
+            if (_os.isLinux() && (!ADOBE_AIR_SDK_LINUX_FILE || !ADOBE_AIR_SDK_LINUX_URL))
+            {
+                log(_viewResourceConstants.ERROR_INVALID_AIR_SDK_URL_LINUX);
+                keepGoing = false;
+            }
+            ADOBE_AIR_SDK_LINUX_URL += ADOBE_AIR_SDK_LINUX_FILE;
 
-             AFE_FILE = data.fontswf.afe.@file.toString();
-             AFE_URL = data.fontswf.afe.@path.toString();
+            ADOBE_FB_GLOBALPLAYER_SWC_FILE = data.flashsdk.versions.children().(@version == FLASH_PLAYER_VERSION).file.toString();
+            ADOBE_FB_GLOBALPLAYER_SWC_URL = data.flashsdk.versions.children().(@version == FLASH_PLAYER_VERSION).path.toString();
+            FLASH_PLAYER_SWF_VERSION = data.flashsdk.versions.children().(@version == FLASH_PLAYER_VERSION).swfversion.toString();
+            if (!ADOBE_FB_GLOBALPLAYER_SWC_FILE || !ADOBE_FB_GLOBALPLAYER_SWC_URL)
+            {
+                log(_viewResourceConstants.ERROR_INVALID_FLASH_PLAYER_SWC_URL);
+                keepGoing = false;
+            }
+            ADOBE_FB_GLOBALPLAYER_SWC_URL += ADOBE_FB_GLOBALPLAYER_SWC_FILE;
 
-             AGLJ40_FILE = data.fontswf.aglj40.@file.toString();
-             AGLJ40_URL = data.fontswf.aglj40.@path.toString();
+            SWF_OBJECT_FILE = data.swfobject.@file.toString();
+            SWF_OBJECT_URL = data.swfobject.@path.toString();
 
-             FLEX_FONTKIT_FILE = data.fontswf["flex-fontkit"].@file.toString();
-             FLEX_FONTKIT_URL = data.fontswf["flex-fontkit"].@path.toString();
+            //Supporting OSMF 2.0 from 4.11 onwards.  
+            if (APACHE_FLEX_BIN_DISTRO_VERSION == "4.9.1" || APACHE_FLEX_BIN_DISTRO_VERSION == "4.10.0")
+            {
+                OSMF_SWC_FILE = data.OSMF_SWC.@file.toString();
+                OSMF_SWC_URL = data.OSMF_SWC.@path.toString();
+                _useOSMF2 = false;
+            }
+            else
+            {
+                OSMF_SWC_FILE = data["OSMF_SWC_2.0"].@file.toString();
+                OSMF_SWC_URL = data["OSMF_SWC_2.0"].@path.toString();
+                _useOSMF2 = true;
+            }
 
-             RIDEAU_FILE = data.fontswf.rideau.@file.toString();
-             RIDEAU_URL = data.fontswf.rideau.@path.toString();
+            BLAZEDS_FILE = data.BlazeDS.@file.toString();
+            BLAZEDS_URL = data.BlazeDS.@path.toString();
 
+            AFE_FILE = data.fontswf.afe.@file.toString();
+            AFE_URL = data.fontswf.afe.@path.toString();
 
-             return keepGoing;
-         }
+            AGLJ40_FILE = data.fontswf.aglj40.@file.toString();
+            AGLJ40_URL = data.fontswf.aglj40.@path.toString();
 
-         protected function updateFlexVersionStrings(selectedFlexVersionObject:Object):void
-         {
-             APACHE_FLEX_BIN_DISTRO_FILE_SHORT = selectedFlexVersionObject.shortName;
-             APACHE_FLEX_BIN_DISTRO_VERSION = selectedFlexVersionObject.version;
-             APACHE_FLEX_BIN_DISTRO_VERSION_DISPLAY = selectedFlexVersionObject.label;
+            FLEX_FONTKIT_FILE = data.fontswf["flex-fontkit"].@file.toString();
+            FLEX_FONTKIT_URL = data.fontswf["flex-fontkit"].@path.toString();
 
-             APACHE_FLEX_BIN_DISTRO_FILE = selectedFlexVersionObject.fileName;
-             APACHE_FLEX_BIN_DISTRO_PATH = selectedFlexVersionObject.path;
-             legacy = selectedFlexVersionObject.legacy;
-             nocache = selectedFlexVersionObject.nocache;
-             APACHE_FLEX_BIN_INSTALLER_FILE = selectedFlexVersionObject.prefix + "installer-config.xml";
+            RIDEAU_FILE = data.fontswf.rideau.@file.toString();
+            RIDEAU_URL = data.fontswf.rideau.@path.toString();
 
-             // ApacheFlex is full URL so download directly and dont use mirror useful for testing release candidates
-             if (APACHE_FLEX_BIN_DISTRO_PATH.indexOf("http") == 0)
-             {
-                 _useMirror = false;
-             }
-             else
-             {
-                 _useMirror = true;
-             }
-         }
 
-         private function useMirrorPath(path:String):String
-         {
-             if (_useMirror)
-             {
-                 return path;
-             }
+            return keepGoing;
+        }
 
-             return "";
-         }
+        protected function updateFlexVersionStrings(selectedFlexVersionObject:Object):void
+        {
+            APACHE_FLEX_BIN_DISTRO_FILE_SHORT = selectedFlexVersionObject.shortName;
+            APACHE_FLEX_BIN_DISTRO_VERSION = selectedFlexVersionObject.version;
+            APACHE_FLEX_BIN_DISTRO_VERSION_DISPLAY = selectedFlexVersionObject.label;
 
-         private function getMirrorURLResultHandler():void
-         {
-             var logMessages:ArrayCollection = ILog(_mirrorURLUtil).log;
-             var i:int;
-             var n:int = logMessages.length;
-             for (i = 0; i < n; i++)
-             {
-                 log(String(logMessages.getItemAt(i)));
-             }
+            APACHE_FLEX_BIN_DISTRO_FILE = selectedFlexVersionObject.fileName;
+            APACHE_FLEX_BIN_DISTRO_PATH = selectedFlexVersionObject.path;
+            legacy = selectedFlexVersionObject.legacy;
+            nocache = selectedFlexVersionObject.nocache;
+            APACHE_FLEX_BIN_INSTALLER_FILE = selectedFlexVersionObject.prefix + "installer-config.xml";
 
-             if (_mirrorURLUtil.errorOccurred)
-             {
-                 abortInstallation("mirrorURLUtil.errorOccurred");
-                 main();
-             }
-             else
-             {
-                 updatePaths();
-             }
+            // ApacheFlex is full URL so download directly and dont use mirror useful for testing release candidates
+            if (APACHE_FLEX_BIN_DISTRO_PATH.indexOf("http") == 0)
+            {
+                _useMirror = false;
+            }
+            else
+            {
+                _useMirror = true;
+            }
 
-         }
+            newSDKSelected = true;
+        }
 
-         protected function updatePaths():void
-         {
-             if (APACHE_FLEX_BIN_DISTRO_PATH.substr(0, Constants.URL_PREFIX.length) == Constants.URL_PREFIX
-                     || APACHE_FLEX_BIN_DISTRO_PATH.substr(0, Constants.FILE_PREFIX.length) == Constants.FILE_PREFIX
-                     || APACHE_FLEX_BIN_DISTRO_PATH.substr(0, Constants.HTTPS_PREFIX.length) == Constants.HTTPS_PREFIX)
-             {
-                 APACHE_FLEX_BIN_DISTRO_URL = APACHE_FLEX_BIN_DISTRO_PATH + APACHE_FLEX_BIN_DISTRO_FILE;
-                 if (stepsOverride != "")
-                 {
-                     APACHE_FLEX_BIN_INSTALLER_URL = stepsOverride;
-                 }
-                 else
-                 {
-                     APACHE_FLEX_BIN_INSTALLER_URL = APACHE_FLEX_BIN_DISTRO_PATH + APACHE_FLEX_BIN_INSTALLER_FILE;
-                 }
-             }
-             else
-             {
-                 APACHE_FLEX_BIN_DISTRO_URL = useMirrorPath(_mirrorURLUtil.mirrorURL) + APACHE_FLEX_BIN_DISTRO_PATH + APACHE_FLEX_BIN_DISTRO_FILE;
-                 if (stepsOverride != "")
-                 {
-                     APACHE_FLEX_BIN_INSTALLER_URL = stepsOverride;
-                 }
-                 else
-                 {
-                     APACHE_FLEX_BIN_INSTALLER_URL = MD5CompareUtil.MD5_DOMAIN + APACHE_FLEX_BIN_DISTRO_PATH + APACHE_FLEX_BIN_INSTALLER_FILE;
-                 }
-             }
+        private function useMirrorPath(path:String):String
+        {
+            if (_useMirror)
+            {
+                return path;
+            }
 
-             if (installerAppPath.substr(0, Constants.URL_PREFIX.length) != Constants.URL_PREFIX)
-             {
-                 installerAppPath = useMirrorPath(_mirrorURLUtil.mirrorURL) + installerAppPath;
-             }
+            return "";
+        }
 
-             main();
-         }
+        private function getMirrorURLResultHandler():void
+        {
+            var logMessages:ArrayCollection = ILog(_mirrorURLUtil).log;
+            var i:int;
+            var n:int = logMessages.length;
+            for (i = 0; i < n; i++)
+            {
+                log(String(logMessages.getItemAt(i)));
+            }
 
-         protected function main():void
-         {
+            if (_mirrorURLUtil.errorOccurred)
+            {
+                abortInstallation("mirrorURLUtil.errorOccurred");
+                main();
+            }
+            else
+            {
+                updatePaths();
+            }
 
-             if (shouldUpdate())
-             {
-                 doUpdate();
-             }
-         }
+        }
 
-         private function logVersion():void
-         {
-             if (!loggedVersion)
-             {
-                 //Current version
-                 var applicationDescriptor:XML = NativeApplication.nativeApplication.applicationDescriptor;
-                 var xmlns:Namespace = new Namespace(applicationDescriptor.namespace());
-                 var currentVersion:String = applicationDescriptor.xmlns::versionNumber.toString();
+        protected function updatePaths():void
+        {
+            if (APACHE_FLEX_BIN_DISTRO_PATH.substr(0, Constants.URL_PREFIX.length) == Constants.URL_PREFIX
+                    || APACHE_FLEX_BIN_DISTRO_PATH.substr(0, Constants.FILE_PREFIX.length) == Constants.FILE_PREFIX
+                    || APACHE_FLEX_BIN_DISTRO_PATH.substr(0, Constants.HTTPS_PREFIX.length) == Constants.HTTPS_PREFIX)
+            {
+                APACHE_FLEX_BIN_DISTRO_URL = APACHE_FLEX_BIN_DISTRO_PATH + APACHE_FLEX_BIN_DISTRO_FILE;
+                if (stepsOverride != "")
+                {
+                    APACHE_FLEX_BIN_INSTALLER_URL = stepsOverride;
+                }
+                else
+                {
+                    APACHE_FLEX_BIN_INSTALLER_URL = APACHE_FLEX_BIN_DISTRO_PATH + APACHE_FLEX_BIN_INSTALLER_FILE;
+                }
+            }
+            else
+            {
+                APACHE_FLEX_BIN_DISTRO_URL = useMirrorPath(_mirrorURLUtil.mirrorURL) + APACHE_FLEX_BIN_DISTRO_PATH + APACHE_FLEX_BIN_DISTRO_FILE;
+                if (stepsOverride != "")
+                {
+                    APACHE_FLEX_BIN_INSTALLER_URL = stepsOverride;
+                }
+                else
+                {
+                    APACHE_FLEX_BIN_INSTALLER_URL = MD5CompareUtil.MD5_DOMAIN + APACHE_FLEX_BIN_DISTRO_PATH + APACHE_FLEX_BIN_INSTALLER_FILE;
+                }
+            }
 
-                 // Log the Installer version to help with any support issues that arise.
-                 log("Installer version " + currentVersion + " (" + _os.os + ")", 0);
-                 loggedVersion = true;
-             }
-         }
+            if (installerAppPath.substr(0, Constants.URL_PREFIX.length) != Constants.URL_PREFIX)
+            {
+                installerAppPath = useMirrorPath(_mirrorURLUtil.mirrorURL) + installerAppPath;
+            }
 
-         protected function shouldUpdate():Boolean
-         {
-             var shouldUpdate:Boolean = false;
-             //Current version
-             var applicationDescriptor:XML = NativeApplication.nativeApplication.applicationDescriptor;
-             var xmlns:Namespace = new Namespace(applicationDescriptor.namespace());
-             var currentVersion:String = applicationDescriptor.xmlns::versionNumber.toString();
+            main();
+        }
 
-             logVersion();
+        protected function main():void
+        {
 
-             var availBuildNumbers:Array = _latestVersion.split(".");
-             var currentBuildNumbers:Array = currentVersion.split(".");
+            if (shouldUpdate())
+            {
+                doUpdate();
+            }
+        }
 
-             if (parseInt(availBuildNumbers[0]) > parseInt(currentBuildNumbers[0]))
-             {
-                 return true;
-             }
-             else if (parseInt(availBuildNumbers[0]) == parseInt(currentBuildNumbers[0]))
-             {
-                 if (parseInt(availBuildNumbers[1]) > parseInt(currentBuildNumbers[1]))
-                 {
-                     return true;
-                 }
-                 else if (parseInt(availBuildNumbers[1]) == parseInt(currentBuildNumbers[1]))
-                 {
-                     if (parseInt(availBuildNumbers[2]) > parseInt(currentBuildNumbers[2]))
-                     {
-                         return true;
-                     }
-                 }
-             }
-             return false;
+        private function logVersion():void
+        {
+            if (!loggedVersion)
+            {
+                //Current version
+                var applicationDescriptor:XML = NativeApplication.nativeApplication.applicationDescriptor;
+                var xmlns:Namespace = new Namespace(applicationDescriptor.namespace());
+                var currentVersion:String = applicationDescriptor.xmlns::versionNumber.toString();
 
-         }
+                // Log the Installer version to help with any support issues that arise.
+                log("Installer version " + currentVersion + " (" + _os.os + ")", 0);
+                loggedVersion = true;
+            }
+        }
 
-         protected function doUpdate():void
-         {
-             var updaterDialog:UpdaterDialog = UpdaterDialog(PopUpManager.createPopUp(this, UpdaterDialog, true));
-             updaterDialog.addEventListener("close", handleUpdaterDialogClose);
-             updaterDialog.latestVersion = _latestVersion;
-             PopUpManager.centerPopUp(updaterDialog);
-         }
+        protected function shouldUpdate():Boolean
+        {
+            var shouldUpdate:Boolean = false;
+            //Current version
+            var applicationDescriptor:XML = NativeApplication.nativeApplication.applicationDescriptor;
+            var xmlns:Namespace = new Namespace(applicationDescriptor.namespace());
+            var currentVersion:String = applicationDescriptor.xmlns::versionNumber.toString();
 
-         protected function handleUpdaterDialogClose(event:Event):void
-         {
-             PopUpManager.removePopUp(IFlexDisplayObject(event.target));
-         }
+            logVersion();
 
-         protected function handleInstallBtnClick(event:MouseEvent):void
-         {
-             var airVersionID:String = airVersion.selectedItem.versionID;
-             var flashVersionID:String = flashPlayerVersion.selectedItem.versionID;
+            var availBuildNumbers:Array = _latestVersion.split(".");
+            var currentBuildNumbers:Array = currentVersion.split(".");
 
-             log("SDK version " + APACHE_FLEX_BIN_DISTRO_VERSION_DISPLAY);
+            if (parseInt(availBuildNumbers[0]) > parseInt(currentBuildNumbers[0]))
+            {
+                return true;
+            }
+            else if (parseInt(availBuildNumbers[0]) == parseInt(currentBuildNumbers[0]))
+            {
+                if (parseInt(availBuildNumbers[1]) > parseInt(currentBuildNumbers[1]))
+                {
+                    return true;
+                }
+                else if (parseInt(availBuildNumbers[1]) == parseInt(currentBuildNumbers[1]))
+                {
+                    if (parseInt(availBuildNumbers[2]) > parseInt(currentBuildNumbers[2]))
+                    {
+                        return true;
+                    }
+                }
+            }
+            return false;
 
-             if (flexVersion.selectedItem.needsAIR)
-             {
-                 if (airVersionID)
-                     log("AIR version " + airVersionID);
-                 else
-                     log("AIR version " + AIR_VERSION);
-             }
+        }
 
-             if (flexVersion.selectedItem.needsFlash)
-             {
-                 if (flashVersionID)
-                     log("Flash Player version " + flashVersionID);
-                 else
-                     log("Flash Player version " + FLASH_PLAYER_VERSION);
-             }
+        protected function doUpdate():void
+        {
+            var updaterDialog:UpdaterDialog = UpdaterDialog(PopUpManager.createPopUp(this, UpdaterDialog, true));
+            updaterDialog.addEventListener("close", handleUpdaterDialogClose);
+            updaterDialog.latestVersion = _latestVersion;
+            PopUpManager.centerPopUp(updaterDialog);
+        }
 
-             if (flexSDKTxtInput.text == "")
-             {
-                 log(_viewResourceConstants.INFO_ENTER_VALID_FLEX_SDK_PATH);
-             }
-             else
-             {
-                 _langSelect.enabled = false;
-                 _flexHome = flexSDKTxtInput.text;
-                 resetInstallStepsActivity();
-                 addOptionalComponentsToInstallSteps();
-                 this.currentState = "installState";
-                 install();
-             }
-         }
+        protected function handleUpdaterDialogClose(event:Event):void
+        {
+            PopUpManager.removePopUp(IFlexDisplayObject(event.target));
+        }
 
-         protected function handleZeroStepNextBtnClick(event:MouseEvent):void
-         {
-             directoryBtn.enabled = false;
+        protected function handleInstallBtnClick(event:MouseEvent):void
+        {
+            var airVersionID:String = airVersion.selectedItem.versionID;
+            var flashVersionID:String = flashPlayerVersion.selectedItem.versionID;
 
-             AIR_VERSION = airVersion.selectedItem.version;
-             var airVersionID:String = airVersion.selectedItem.versionID;
-             FLASH_PLAYER_VERSION = flashPlayerVersion.selectedItem.version;
-             var flashVersionID:String = flashPlayerVersion.selectedItem.versionID;
+            log("SDK version " + APACHE_FLEX_BIN_DISTRO_VERSION_DISPLAY);
 
-             setXMLVariables(); // as AIR and Flash version may of changed
+            if (flexVersion.selectedItem.needsAIR)
+            {
+                if (airVersionID)
+                {
+                    log("AIR version " + airVersionID);
+                }
+                else
+                {
+                    log("AIR version " + AIR_VERSION);
+                }
+            }
 
-             if (!legacy)
-             {
-                 var req:URLRequest = new URLRequest(APACHE_FLEX_BIN_INSTALLER_URL);
-                 loader = new URLLoader();
-                 loader.dataFormat = URLLoaderDataFormat.TEXT;
-                 loader.addEventListener(Event.COMPLETE, handleInstallerXMLLoaded);
-                 loader.addEventListener(ErrorEvent.ERROR, handleInstallerXMLError);
-                 loader.addEventListener(IOErrorEvent.IO_ERROR, handleInstallIOXMLError);
+            if (flexVersion.selectedItem.needsFlash)
+            {
+                if (flashVersionID)
+                {
+                    log("Flash Player version " + flashVersionID);
+                }
+                else
+                {
+                    log("Flash Player version " + FLASH_PLAYER_VERSION);
+                }
+            }
 
-                 loader.load(req);
-             }
-             else
-             {
-                 showDirectoryState();
-             }
-         }
+            if (flexSDKTxtInput.text == "")
+            {
+                log(_viewResourceConstants.INFO_ENTER_VALID_FLEX_SDK_PATH);
+            }
+            else
+            {
+                _langSelect.enabled = false;
+                _flexHome = flexSDKTxtInput.text;
+                resetInstallStepsActivity();
+                addOptionalComponentsToInstallSteps();
+                this.currentState = "installState";
+                install();
+            }
+        }
 
-         protected function handleFirstStepBackBtnClick(event:MouseEvent):void
-         {
-             showDefaultState();
-         }
+        protected function handleZeroStepNextBtnClick(event:MouseEvent):void
+        {
+            directoryBtn.enabled = false;
 
-         protected function handleSecondStepBackBtnClick(event:MouseEvent):void
-         {
-             showDirectoryState();
-         }
+            AIR_VERSION = airVersion.selectedItem.version;
+            var airVersionID:String = airVersion.selectedItem.versionID;
+            FLASH_PLAYER_VERSION = flashPlayerVersion.selectedItem.version;
+            var flashVersionID:String = flashPlayerVersion.selectedItem.versionID;
 
-         protected function handleFirstStepNextBtnClick(event:MouseEvent):void
-         {
-             // Quick check to see if the selected directory is writable
-             try
-             {
-                 var f:File = new File(_flexHome + File.separator + "flex.txt");
-                 checkDirWritable(f);
-             }
-             catch (e:Error)
-             {
-                 log(_viewResourceConstants.ERROR_UNABLE_TO_CREATE_TEMP_DIRECTORY);
-                 flexSDKTxtInput.errorString = _viewResourceConstants.ERROR_DIR_REQUIRE_ADMIN_RIGHTS;
-                 flexSDKTxtInput.prompt = _viewResourceConstants.ERROR_DIR_REQUIRE_ADMIN_RIGHTS;
-                 updateActivityStep(_viewResourceConstants.STEP_CREATE_DIRECTORIES, StepItem.ERROR);
-                 return;
-             }
+            setXMLVariables(); // as AIR and Flash version may of changed
 
-             showOptionsState();
-         }
+            if (!legacy)
+            {
+                if (newSDKSelected)
+                {
+                    var req:URLRequest = new URLRequest(APACHE_FLEX_BIN_INSTALLER_URL);
+                    loader = new ApacheURLLoader();
+                    loader.dataFormat = URLLoaderDataFormat.TEXT;
+                    loader.addEventListener(Event.COMPLETE, handleInstallerXMLLoaded);
+                    loader.addEventListener(ErrorEvent.ERROR, handleInstallerXMLError);
+                    loader.addEventListener(IOErrorEvent.IO_ERROR, handleInstallerXMLError);
 
-         protected function handleInstallerXMLLoaded(event:Event):void
-         {
-             var data:XML = XML(event.target.data);
-             var localeList:Array = resourceManager.localeChain;
-             _installerComponentsDataProvider = new ArrayCollection();
-             var compList:XMLList = data.component;
-             for each (var comp:XML in compList)
-             {
-                 var vo:InstallerComponentVO = new InstallerComponentVO(getLocalizedString(comp, "label"),
-                         getLocalizedString(comp, "message"), getLocalizedString(comp, "license"),
-                         getLocalizedString(comp, "licenseURL"),
-                         comp.@id.toString(), comp.@required.toString() == "true");
-                 licensePropertyMap[comp.@property.toString()] = vo;
-                 _installerComponentsDataProvider.addItem(vo);
-             }
-             usingXML = true;
-             installStepsData = data.steps.step;
-             var strings:XMLList = data.strings.string;
-             for each (var x:XML in strings)
-             {
-                 var id:String = x.@id.toString();
-                 if (id in _viewResourceConstants)
-                 {
-                     var val:String = getLocalizedString(x, null);
-                     _viewResourceConstants[id] = val;
-                     var pce:PropertyChangeEvent = PropertyChangeEvent.createUpdateEvent(this, id, "", val);
-                     _viewResourceConstants.dispatchEvent(pce);
-                 }
-             }
-             var props:XMLList = data.properties.property;
-             for each (x in props)
-             {
-                 additionalProps[x.@name.toString()] = x.@value.toString();
-             }
-             currentState = "directoryState";
-         }
+                    loader.load(req);
+                }
+            }
+            else
+            {
+                showDirectoryState();
+            }
+        }
 
-         private function getLocalizedString(xml:XML, propName:String):String
-         {
-             var compBundle:XMLList;
-             for each (var locale:String in resourceManager.localeChain)
-             {
-                 compBundle = xml[locale];
-                 if (compBundle.length() == 1)
-                 {
-                     if (propName)
-                     {
-                         var xmlList:XMLList = compBundle[0][propName];
-                         if (xmlList.length() == 1)
-                         {
-                             return xmlList[0].toString();
-                         }
-                     }
-                     else
-                     {
-                         var s:String = compBundle[0].toString();
-                         if (s.length > 0)
-                             return s;
-                     }
-                 }
-             }
-             return "";
-         }
+        protected function handleFirstStepBackBtnClick(event:MouseEvent):void
+        {
+            showDefaultState();
+        }
 
-         protected function handleInstallerXMLError(event:Event):void
-         {
-             log("Unable to load " + APACHE_FLEX_BIN_INSTALLER_URL);
-             abortInstallation("Unable to load " + APACHE_FLEX_BIN_INSTALLER_URL);
-         }
+        protected function handleSecondStepBackBtnClick(event:MouseEvent):void
+        {
+            showDirectoryState();
+        }
 
-         protected function handleInstallIOXMLError(event:IOErrorEvent):void
-         {
-             // Stream Error 2032 here means that the SSL connection can't be created.  TLS/SSL error?
-             log("Unable to load " + APACHE_FLEX_BIN_INSTALLER_URL + " with  " + event.text);
-             abortInstallation("Unable to load " + APACHE_FLEX_BIN_INSTALLER_URL);
-         }
+        protected function handleFirstStepNextBtnClick(event:MouseEvent):void
+        {
+            // Quick check to see if the selected directory is writable
+            try
+            {
+                var f:File = new File(_flexHome + File.separator + "flex.txt");
+                checkDirWritable(f);
+            }
+            catch (e:Error)
+            {
+                log(_viewResourceConstants.ERROR_UNABLE_TO_CREATE_TEMP_DIRECTORY);
+                flexSDKTxtInput.errorString = _viewResourceConstants.ERROR_DIR_REQUIRE_ADMIN_RIGHTS;
+                flexSDKTxtInput.prompt = _viewResourceConstants.ERROR_DIR_REQUIRE_ADMIN_RIGHTS;
+                updateActivityStep(_viewResourceConstants.STEP_CREATE_DIRECTORIES, StepItem.ERROR);
+                return;
+            }
 
-         protected function showDefaultState():void
-         {
-             zeroStepGroup.visible = true;
-             directoryBtn.enabled = true;
-             currentState = "default";
-         }
+            showOptionsState();
+        }
 
-         protected function showDirectoryState():void
-         {
-             initiateInstallStepsActivity();
-             if (currentState != "optionsState")
-             {
-                 initializeInstallerComponentsDataProvider();
-             }
-             currentState = "directoryState";
-         }
+        protected function handleInstallerXMLLoaded(event:Event):void
+        {
+            var data:XML = XML(event.target.data);
+            var localeList:Array = resourceManager.localeChain;
+            _installerComponentsDataProvider = new ArrayCollection();
+            compList = data.component.copy();
+            for each (var comp:XML in compList)
+            {
+                var vo:InstallerComponentVO = new InstallerComponentVO(getLocalizedString(comp, "label"),
+                        getLocalizedString(comp, "message"), getLocalizedString(comp, "license"),
+                        getLocalizedString(comp, "licenseURL"),
+                        comp.@id.toString(), comp.@required.toString() == "true");
+                licensePropertyMap[comp.@property.toString()] = vo;
+                _installerComponentsDataProvider.addItem(vo);
+            }
+            usingXML = true;
+            // progressLabels = data.progressLabels[0];
+            installStepsData = data.steps.step;
+            var strings:XMLList = data.strings.string;
+            for each (var x:XML in strings)
+            {
+                var id:String = x.@id.toString();
+                if (id in _viewResourceConstants)
+                {
+                    var val:String = getLocalizedString(x, null);
+                    _viewResourceConstants[id] = val;
+                    var pce:PropertyChangeEvent = PropertyChangeEvent.createUpdateEvent(this, id, "", val);
+                    _viewResourceConstants.dispatchEvent(pce);
+                }
+            }
+            var props:XMLList = data.properties.property;
+            for each (x in props)
+            {
+                additionalProps[x.@name.toString()] = x.@value.toString();
+            }
+            currentState = "directoryState";
+            System.disposeXML(data);
+        }
 
-         protected function showOptionsState():void
-         {
-             currentState = "optionsState";
-             checkIfAllRequiredComponentsPromptsAnswered();
-         }
+        private function getLocalizedString(xml:XML, propName:String):String
+        {
+            var compBundle:XMLList;
+            for each (var locale:String in resourceManager.localeChain)
+            {
+                compBundle = xml[locale];
+                if (compBundle.length() == 1)
+                {
+                    if (propName)
+                    {
+                        var xmlList:XMLList = compBundle[0][propName];
+                        if (xmlList.length() == 1)
+                        {
+                            return xmlList[0].toString();
+                        }
+                    }
+                    else
+                    {
+                        var s:String = compBundle[0].toString();
+                        if (s.length > 0)
+                        {
+                            return s;
+                        }
+                    }
+                }
+            }
+            return "";
+        }
 
-         protected function initiateInstallStepsActivity():void
-         {
-             _installationSteps = new ArrayCollection();
+        protected function handleInstallerXMLError(event:Event):void
+        {
+            log("Unable to load " + APACHE_FLEX_BIN_INSTALLER_URL);
+            abortInstallation("Unable to load " + APACHE_FLEX_BIN_INSTALLER_URL);
+        }
 
-             _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_CREATE_DIRECTORIES));
-             _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_REQUIRED_INSTALL_APACHE_FLEX_SDK));
-             _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_VERIFY_FLEX_SDK));
-             _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_UNZIP_FLEX_SDK));
-             _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK));
-             _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_UNZIP_AIR_RUNTIME_KIT));
-             _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_REQUIRED_INSTALL_FLASH_PLAYER_GLOBAL_SWC));
-             _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_INSTALL_CONFIG_FILES));
-             _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_REQUIRED_INSTALL_SWFOBJECT));
-             _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF));
-         }
+        protected function showDefaultState():void
+        {
+            zeroStepGroup.visible = true;
+            directoryBtn.enabled = true;
+            currentState = "default";
+        }
 
-         protected function resetInstallStepsActivity():void
-         {
-             for each(var step:StepItem in _installationSteps)
-             {
-                 step.status = StepItem.NORMAL;
-             }
-         }
+        protected function showDirectoryState():void
+        {
+            initiateInstallStepsActivity();
+            if (currentState != "optionsState")
+            {
+                initializeInstallerComponentsDataProvider();
+            }
+            currentState = "directoryState";
+        }
 
-         protected function addOptionalComponentsToInstallSteps():void
-         {
-             if (usingXML)
-             {
-                 _installationSteps = new ArrayCollection();
+        protected function showOptionsState():void
+        {
+            currentState = "optionsState";
+            checkIfAllRequiredComponentsPromptsAnswered();
+        }
 
-                 _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_CREATE_DIRECTORIES));
-                 _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_REQUIRED_INSTALL_APACHE_FLEX_SDK));
-                 _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_VERIFY_FLEX_SDK));
-                 _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_UNZIP_FLEX_SDK));
+        protected function initiateInstallStepsActivity():void
+        {
+            _installationSteps = new ArrayCollection();
 
-                 for each (var stepData:XML in installStepsData)
-                 {
-                     var propName:String = stepData.@property.toString();
-                     if (!propName || InstallerComponentVO(licensePropertyMap[propName]).selected)
-                     {
-                         var si:StepItem = new StepItem(getLocalizedString(stepData, null));
-                         _installationSteps.addItem(si);
-                         stepIDs.push(stepData.@id.toString());
-                         stepLabels.push(si.label);
-                     }
-                 }
-                 return;
-             }
-             for each (var obj:InstallerComponentVO in _installerComponentsDataProvider)
-             {
-                 if (!obj.required && obj.selected)
-                 {
-                     _installationSteps.addItem(new StepItem(obj.label));
-                 }
-             }
-         }
+            _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_CREATE_DIRECTORIES));
+            _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_REQUIRED_INSTALL_APACHE_FLEX_SDK));
+            _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_VERIFY_FLEX_SDK));
+            _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_UNZIP_FLEX_SDK));
+            _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK));
+            _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_UNZIP_AIR_RUNTIME_KIT));
+            _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_REQUIRED_INSTALL_FLASH_PLAYER_GLOBAL_SWC));
+            _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_INSTALL_CONFIG_FILES));
+            _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_REQUIRED_INSTALL_SWFOBJECT));
+            _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF));
+        }
 
-         protected function initializeInstallerComponentsDataProvider():void
-         {
-             _installerComponentsDataProvider = new ArrayCollection();
-             _installerComponentsDataProvider.addItem(new InstallerComponentVO(_viewResourceConstants.STEP_REQUIRED_INSTALL_APACHE_FLEX_SDK,
-                     _viewResourceConstants.ASK_APACHE_FLEX, _viewResourceConstants.LICENSE_APACHE_V2,
-                     _viewResourceConstants.LICENSE_URL_APACHE_V2,
-                     "STEP_REQUIRED_INSTALL_APACHE_FLEX_SDK", true));
-             _installerComponentsDataProvider.addItem(new InstallerComponentVO(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK,
-                     _viewResourceConstants.ASK_ADOBE_AIR_SDK,
-                     _viewResourceConstants.LICENSE_ADOBE_AIR_SDK,
-                     _viewResourceConstants.LICENSE_URL_ADOBE_AIR_SDK,
-                     "STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK", true));
-             _installerComponentsDataProvider.addItem(new InstallerComponentVO(_viewResourceConstants.STEP_REQUIRED_INSTALL_FLASH_PLAYER_GLOBAL_SWC,
-                     _viewResourceConstants.ASK_ADOBE_FLASH_PLAYER_GLOBAL_SWC,
-                     _viewResourceConstants.LICENSE_ADOBE_SDK,
-                     _viewResourceConstants.LICENSE_URL_ADOBE_SDK,
-                     "STEP_REQUIRED_INSTALL_FLASH_PLAYER_GLOBAL_SWC", true));
-             _installerComponentsDataProvider.addItem(new InstallerComponentVO(_viewResourceConstants.STEP_REQUIRED_INSTALL_SWFOBJECT,
-                     _viewResourceConstants.ASK_SWFOBJECT, _viewResourceConstants.LICENSE_SWFOBJECT,
-                     _viewResourceConstants.LICENSE_URL_SWFOBJECT, "STEP_REQUIRED_INSTALL_SWFOBJECT",
-                     true));
-             _installerComponentsDataProvider.addItem(new InstallerComponentVO(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF,
-                     _viewResourceConstants.ASK_OSMF, _viewResourceConstants.LICENSE_OSMF,
-                     _viewResourceConstants.LICENSE_URL_OSMF, "STEP_REQUIRED_INSTALL_OSMF", true));
-             _installerComponentsDataProvider.addItem(new InstallerComponentVO(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF,
-                     _viewResourceConstants.ASK_FONTSWF, _viewResourceConstants.LICENSE_FONTSWF,
-                     _viewResourceConstants.LICENSE_URL_FONTSWF, "STEP_OPTIONAL_INSTALL_FONTSWF",
-                     false));
-             _installerComponentsDataProvider.addItem(new InstallerComponentVO(_viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS,
-                     _viewResourceConstants.ASK_BLAZEDS, _viewResourceConstants.LICENSE_BLAZEDS,
-                     _viewResourceConstants.LICENSE_URL_BLAZEDS, "STEP_OPTIONAL_INSTALL_BLAZEDS",
-                     false));
-         }
+        protected function resetInstallStepsActivity():void
+        {
+            for each(var step:StepItem in _installationSteps)
+            {
+                step.status = StepItem.NORMAL;
+            }
+        }
 
-         protected function install():void
-         {
-             createDirectories();
-         }
+        protected function addOptionalComponentsToInstallSteps():void
+        {
+            if (usingXML)
+            {
+                _installationSteps = new ArrayCollection();
 
-         protected function handleAirVersionChange(event:Event):void
-         {
-             AIR_VERSION = airVersion.selectedItem.version;
+                _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_CREATE_DIRECTORIES));
+                _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_REQUIRED_INSTALL_APACHE_FLEX_SDK));
+                _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_VERIFY_FLEX_SDK));
+                _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_UNZIP_FLEX_SDK));
 
-             // Match AIR and Flash versions
-             if (flashPlayerVersion.selectedIndex != airVersion.selectedIndex)
-             {
-                 flashPlayerVersion.selectedIndex = airVersion.selectedIndex;
-                 FLASH_PLAYER_VERSION = FLASH_PLAYER_VERSIONS[airVersion.selectedIndex].version;
-             }
-         }
+                for each (var stepData:XML in installStepsData)
+                {
+                    var propName:String = stepData.@property.toString();
+                    if (!propName || InstallerComponentVO(licensePropertyMap[propName]).selected)
+                    {
+                        var si:StepItem = new StepItem(getLocalizedString(stepData, null));
+                        _installationSteps.addItem(si);
+                        stepIDs.push(stepData.@id.toString());
+                        stepLabels.push(si.label);
+                    }
+                }
+                return;
+            }
+            for each (var obj:InstallerComponentVO in _installerComponentsDataProvider)
+            {
+                if (!obj.required && obj.selected)
+                {
+                    _installationSteps.addItem(new StepItem(obj.label));
+                }
+            }
+        }
 
-         protected function handleFlashPlayerVersionChange(event:Event):void
-         {
-             FLASH_PLAYER_VERSION = flashPlayerVersion.selectedItem.version;
+        protected function initializeInstallerComponentsDataProvider():void
+        {
+            var versionNum:int = int(APACHE_FLEX_BIN_DISTRO_VERSION.split('.').join(''));
+            _installerComponentsDataProvider = new ArrayCollection();
+            /**
+             * version 4.13.0 of the SDK is when the installer started using the new xml based
+             * way of displaying/updating required or optional components of the installer
+             */
+            if (usingXML && (versionNum >= 4130))
+            {
+                for each (var comp:XML in compList)
+                {
+                    var vo:InstallerComponentVO = new InstallerComponentVO(getLocalizedString(comp, "label"),
+                            getLocalizedString(comp, "message"), getLocalizedString(comp, "license"),
+                            getLocalizedString(comp, "licenseURL"),
+                            comp.@id.toString(), comp.@required.toString() == "true");
+                    licensePropertyMap[comp.@property.toString()] = vo;
+                    _installerComponentsDataProvider.addItem(vo);
+                }
+            }
+            else
+            {
+                _installerComponentsDataProvider.addItem(new InstallerComponentVO(_viewResourceConstants.STEP_REQUIRED_INSTALL_APACHE_FLEX_SDK,
+                        _viewResourceConstants.ASK_APACHE_FLEX, _viewResourceConstants.LICENSE_APACHE_V2,
+                        _viewResourceConstants.LICENSE_URL_APACHE_V2,
+                        "STEP_REQUIRED_INSTALL_APACHE_FLEX_SDK", true));
+                _installerComponentsDataProvider.addItem(new InstallerComponentVO(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK,
+                        _viewResourceConstants.ASK_ADOBE_AIR_SDK,
+                        _viewResourceConstants.LICENSE_ADOBE_AIR_SDK,
+                        _viewResourceConstants.LICENSE_URL_ADOBE_AIR_SDK,
+                        "STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK", true));
+                _installerComponentsDataProvider.addItem(new InstallerComponentVO(_viewResourceConstants.STEP_REQUIRED_INSTALL_FLASH_PLAYER_GLOBAL_SWC,
+                        _viewResourceConstants.ASK_ADOBE_FLASH_PLAYER_GLOBAL_SWC,
+                        _viewResourceConstants.LICENSE_ADOBE_SDK,
+                        _viewResourceConstants.LICENSE_URL_ADOBE_SDK,
+                        "STEP_REQUIRED_INSTALL_FLASH_PLAYER_GLOBAL_SWC", true));
+                _installerComponentsDataProvider.addItem(new InstallerComponentVO(_viewResourceConstants.STEP_REQUIRED_INSTALL_SWFOBJECT,
+                        _viewResourceConstants.ASK_SWFOBJECT,
+                        _viewResourceConstants.LICENSE_SWFOBJECT,
+                        _viewResourceConstants.LICENSE_URL_SWFOBJECT,
+                        "STEP_REQUIRED_INSTALL_SWFOBJECT", true));
+                _installerComponentsDataProvider.addItem(new InstallerComponentVO(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF,
+                        _viewResourceConstants.ASK_OSMF,
+                        _viewResourceConstants.LICENSE_OSMF,
+                        _viewResourceConstants.LICENSE_URL_OSMF,
+                        "STEP_REQUIRED_INSTALL_OSMF", true));
+                _installerComponentsDataProvider.addItem(new InstallerComponentVO(_viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS,
+                        _viewResourceConstants.ASK_BLAZEDS,
+                        _viewResourceConstants.LICENSE_BLAZEDS,
+                        _viewResourceConstants.LICENSE_URL_BLAZEDS,
+                        "STEP_OPTIONAL_INSTALL_BLAZEDS", false));
+                _installerComponentsDataProvider.addItem(new InstallerComponentVO(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF,
+                        _viewResourceConstants.ASK_FONTSWF,
+                        _viewResourceConstants.LICENSE_FONTSWF,
+                        _viewResourceConstants.LICENSE_URL_FONTSWF,
+                        "STEP_OPTIONAL_INSTALL_FONTSWF", false));
+//              _installerComponentsDataProvider.addItem(new InstallerComponentVO(_viewResourceConstants.STEP_REQUIRED_INSTALL_OFL_FONTS,
+//                      _viewResourceConstants.ASK_OFL_FONTS,
+//                      _viewResourceConstants.LICENSE_OFL_FONTS,
+//                      _viewResourceConstants.LICENSE_URL_OFL_FONTS,
+//                      "STEP_REQUIRED_INSTALL_OFL_FONTS", true));
+            }
+        }
 
-             // Match AIR and Flash versions
-             if (airVersion.selectedIndex != flashPlayerVersion.selectedIndex)
-             {
-                 airVersion.selectedIndex = flashPlayerVersion.selectedIndex;
-                 AIR_VERSION = AIR_VERSIONS[flashPlayerVersion.selectedIndex].version;
-             }
-         }
+        protected function install():void
+        {
+            createDirectories();
+        }
 
-         protected function handleFlexVersionChange(event:Event):void
-         {
-             var item:Object = flexVersion.selectedItem;
-             airVersion.enabled = item.needsAIR;
-             flashPlayerVersion.enabled = item.needsFlash;
-             updateFlexVersionStrings(item);
-             updatePaths();
-             updateWindowTitle();
-             InstallApacheFlexSkin(skin).textIcon.source = item.icon;
-         }
+        protected function handleAirVersionChange(event:Event):void
+        {
+            AIR_VERSION = airVersion.selectedItem.version;
 
-         protected function browseForSDK(event:MouseEvent):void
-         {
-             var file:File = new File();
+            // Match AIR and Flash versions
+            if (flashPlayerVersion.selectedIndex != airVersion.selectedIndex)
+            {
+                flashPlayerVersion.selectedIndex = airVersion.selectedIndex;
+                FLASH_PLAYER_VERSION = FLASH_PLAYER_VERSIONS[airVersion.selectedIndex].version;
+            }
+        }
 
-             file.addEventListener(Event.SELECT, flexSDKDirSelected, false, 0, true);
-             file.browseForDirectory(_viewResourceConstants.INFO_SELECT_DIRECTORY);
-         }
+        protected function handleFlashPlayerVersionChange(event:Event):void
+        {
+            FLASH_PLAYER_VERSION = flashPlayerVersion.selectedItem.version;
 
-         protected function checkDirWritable(file:File):void
-         {
-             var ba:ByteArray = new ByteArray();
-             ba.writeUTFBytes("1");
-             writeFileToDirectory(file, ba);
-             file.deleteFile();
-         }
+            // Match AIR and Flash versions
+            if (airVersion.selectedIndex != flashPlayerVersion.selectedIndex)
+            {
+                airVersion.selectedIndex = flashPlayerVersion.selectedIndex;
+                AIR_VERSION = AIR_VERSIONS[flashPlayerVersion.selectedIndex].version;
+            }
+        }
 
-         protected function flexSDKDirSelected(event:Event):void
-         {
-             var selectedDir:File = File(event.target);
-             var overlay:Boolean = flexVersion.selectedItem.overlay;
+        protected function handleFlexVersionChange(event:Event):void
+        {
+            /*APACHE_FLEX_BIN_DISTRO_VERSION =  flexVersion.selectedItem.version;
+             APACHE_FLEX_BIN_DISTRO_VERSION_DISPLAY = flexVersion.selectedItem.label;*/
+            var item:Object = flexVersion.selectedItem;
+            airVersion.enabled = item.needsAIR;
+            flashPlayerVersion.enabled = item.needsFlash;
+            updateFlexVersionStrings(item);
+            updatePaths();
+            updateWindowTitle();
+            InstallApacheFlexSkin(skin).textIcon.source = item.icon;
+        }
 
-             // Quick check to see if the selected directory is writable
-             try
-             {
-                 var f:File = new File(selectedDir.nativePath + File.separator + "flex.txt");
-                 checkDirWritable(f);
-             }
-             catch (e:Error)
-             {
-                 log(_viewResourceConstants.ERROR_UNABLE_TO_CREATE_TEMP_DIRECTORY);
-                 log(_viewResourceConstants.ERROR_DIR_REQUIRE_ADMIN_RIGHTS);
-                 flexSDKTxtInput.text = selectedDir.nativePath;
-                 flexSDKTxtInput.errorString = _viewResourceConstants.ERROR_DIR_REQUIRE_ADMIN_RIGHTS + " : " + selectedDir.nativePath; // tooltip
-                 flexSDKTxtInput.prompt = _viewResourceConstants.ERROR_DIR_REQUIRE_ADMIN_RIGHTS; // field
-                 updateActivityStep(_viewResourceConstants.STEP_CREATE_DIRECTORIES, StepItem.ERROR);
-                 return;
-             }
+        protected function browseForSDK(event:MouseEvent):void
+        {
+            var file:File = new File();
 
-             overlaying = overlay;
-             if (!overlay)
-             {
-                 if (isDirectoryEmpty(selectedDir))
-                 {
-                     _flexHome = selectedDir.nativePath;
-                     flexSDKTxtInput.text = _flexHome;
-                     nextBtn.enabled = true;
-                     _langSelect.enabled = true;
-                     flexSDKTxtInput.errorString = "";
-                     flexSDKTxtInput.prompt = _viewResourceConstants.SELECT_PATH_PROMPT;
-                 }
-                 else
-                 {
-                     nextBtn.enabled = false;
-                     flexSDKTxtInput.text = selectedDir.nativePath;
-                     flexSDKTxtInput.errorString = _viewResourceConstants.ERROR_DIR_NOT_EMPTY + " : " + selectedDir.nativePath;
-                     flexSDKTxtInput.prompt = _viewResourceConstants.ERROR_DIR_NOT_EMPTY;
-                 }
-             }
-             else
-             {
-                 _flexHome = selectedDir.nativePath;
-                 flexSDKTxtInput.text = _flexHome;
-                 nextBtn.enabled = true;
-                 _langSelect.enabled = true;
-                 flexSDKTxtInput.errorString = "";
-                 flexSDKTxtInput.prompt = _viewResourceConstants.SELECT_PATH_PROMPT;
-             }
-         }
+            file.addEventListener(Event.SELECT, flexSDKDirSelected, false, 0, true);
+            file.browseForDirectory(_viewResourceConstants.INFO_SELECT_DIRECTORY);
+        }
 
-         protected function handleFlexSDXTxtInputChange(event:TextOperationEvent):void
-         {
-             var tempDir:File;
-             var path:String = flexSDKTxtInput.text;
+        protected function checkDirWritable(file:File):void
+        {
+            var ba:ByteArray = new ByteArray();
+            ba.writeUTFBytes("1");
+            writeFileToDirectory(file, ba);
+            file.deleteFile();
+        }
 
-             try
-             {
-                 tempDir = new File(path);
+        protected function flexSDKDirSelected(event:Event):void
+        {
+            var selectedDir:File = File(event.target);
+            var overlay:Boolean = flexVersion.selectedItem.overlay;
 
-                 if (isDirectoryEmpty(tempDir))
-                 {
-                     flexSDKTxtInput.errorString = "";
-                     _flexHome = path;
-                     nextBtn.enabled = true;
-                     _langSelect.enabled = true;
-                 }
-                 else
-                 {
-                     flexSDKTxtInput.errorString = _viewResourceConstants.ERROR_INVALID_FLEX_SDK_DIRECTORY;
-                     nextBtn.enabled = false;
-                 }
-             }
-             catch (e:Error)
-             {
-                 flexSDKTxtInput.errorString = _viewResourceConstants.ERROR_INVALID_FLEX_SDK_DIRECTORY;
-                 nextBtn.enabled = false;
-             }
-         }
+            // Quick check to see if the selected directory is writable
+            try
+            {
+                var f:File = new File(selectedDir.nativePath + File.separator + "flex.txt");
+                checkDirWritable(f);
+            }
+            catch (e:Error)
+            {
+                log(_viewResourceConstants.ERROR_UNABLE_TO_CREATE_TEMP_DIRECTORY);
+                log(_viewResourceConstants.ERROR_DIR_REQUIRE_ADMIN_RIGHTS);
+                flexSDKTxtInput.text = selectedDir.nativePath;
+                flexSDKTxtInput.errorString = _viewResourceConstants.ERROR_DIR_REQUIRE_ADMIN_RIGHTS + " : " + selectedDir.nativePath; // tooltip
+                flexSDKTxtInput.prompt = _viewResourceConstants.ERROR_DIR_REQUIRE_ADMIN_RIGHTS; // field
+                updateActivityStep(_viewResourceConstants.STEP_CREATE_DIRECTORIES, StepItem.ERROR);
+                return;
+            }
 
-         protected function createDirectories():void
-         {
-             updateActivityStep(_viewResourceConstants.STEP_CREATE_DIRECTORIES, StepItem.ACTIVE);
+            overlaying = overlay;
+            if (!overlay)
+            {
+                if (isDirectoryEmpty(selectedDir))
+                {
+                    _flexHome = selectedDir.nativePath;
+                    flexSDKTxtInput.text = _flexHome;
+                    nextBtn.enabled = true;
+                    _langSelect.enabled = true;
+                    flexSDKTxtInput.errorString = "";
+                    flexSDKTxtInput.prompt = _viewResourceConstants.SELECT_PATH_PROMPT;
+                }
+                else
+                {
+                    nextBtn.enabled = false;
+                    flexSDKTxtInput.text = selectedDir.nativePath;
+                    flexSDKTxtInput.errorString = _viewResourceConstants.ERROR_DIR_NOT_EMPTY + " : " + selectedDir.nativePath;
+                    flexSDKTxtInput.prompt = _viewResourceConstants.ERROR_DIR_NOT_EMPTY;
+                }
+            }
+            else
+            {
+                _flexHome = selectedDir.nativePath;
+                flexSDKTxtInput.text = _flexHome;
+                nextBtn.enabled = true;
+                _langSelect.enabled = true;
+                flexSDKTxtInput.errorString = "";
+                flexSDKTxtInput.prompt = _viewResourceConstants.SELECT_PATH_PROMPT;
+            }
+        }
 
-             try
-             {
-                 if (!overlaying)
-                     log(_viewResourceConstants.INFO_CREATING_FLEX_HOME);
-                 _flexHomeDir = createFolder(_flexHome);
-                 log(_viewResourceConstants.INFO_CREATING_TEMP_DIR);
-                 _flexTemp = _flexHome + File.separator + "temp";
-                 _flexTempDir = createFolder(_flexTemp);
-                 updateActivityStep(_viewResourceConstants.STEP_CREATE_DIRECTORIES, StepItem.COMPLETE);
-                 downloadApacheFlexSDK();
-             }
-             catch (e:Error)
-             {
-                 updateActivityStep(_viewResourceConstants.STEP_CREATE_DIRECTORIES, StepItem.ERROR);
-                 log(_viewResourceConstants.ERROR_UNABLE_TO_CREATE_TEMP_DIRECTORY);
-                 abortInstallation(_viewResourceConstants.ERROR_UNABLE_TO_CREATE_TEMP_DIRECTORY);
-             }
-         }
+        protected function handleFlexSDXTxtInputChange(event:TextOperationEvent):void
+        {
+            var tempDir:File;
+            var path:String = flexSDKTxtInput.text;
 
-         protected function downloadApacheFlexSDK():void
-         {
-             updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_APACHE_FLEX_SDK, StepItem.ACTIVE);
+            try
+            {
+                tempDir = new File(path);
 
-             try
-             {
-                 log(_viewResourceConstants.INFO_DOWNLOADING_FLEX_SDK + APACHE_FLEX_BIN_DISTRO_URL);
-                 _apacheFlexSDKCompressedFile = File.userDirectory.resolvePath(_flexTemp + File.separator + APACHE_FLEX_BIN_DISTRO_FILE);
-                 copyOrDownload(APACHE_FLEX_BIN_DISTRO_URL, handleApacheFlexSDKDownload, _apacheFlexSDKCompressedFile, handleApacheFlexSDKDownloadError, nocache);
-             }
-             catch (e:Error)
-             {
-                 updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_APACHE_FLEX_SDK, StepItem.ERROR);
-                 log(_viewResourceConstants.ERROR_UNABLE_TO_CREATE_TEMP_DIRECTORY + "(error: " + e.message);
-                 abortInstallation(_viewResourceConstants.ERROR_UNABLE_TO_CREATE_TEMP_DIRECTORY + "(error: " + e.message);
-             }
+                if (isDirectoryEmpty(tempDir))
+                {
+                    flexSDKTxtInput.errorString = "";
+                    _flexHome = path;
+                    nextBtn.enabled = true;
+                    _langSelect.enabled = true;
+                }
+                else
+                {
+                    flexSDKTxtInput.errorString = _viewResourceConstants.ERROR_INVALID_FLEX_SDK_DIRECTORY;
+                    nextBtn.enabled = false;
+                }
+            }
+            catch (e:Error)
+            {
+                flexSDKTxtInput.errorString = _viewResourceConstants.ERROR_INVALID_FLEX_SDK_DIRECTORY;
+                nextBtn.enabled = false;
+            }
+        }
 
-         }
+        protected function createDirectories():void
+        {
+            updateActivityStep(_viewResourceConstants.STEP_CREATE_DIRECTORIES, StepItem.ACTIVE);
 
-         protected function handleApacheFlexSDKDownload(event:Event):void
-         {
-             try
-             {
-                 writeFileToDirectory(_apacheFlexSDKCompressedFile, event.target.data);
-             }
-             catch (e:Error)
-             {
-                 updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_APACHE_FLEX_SDK, StepItem.ERROR);
-                 abortInstallation("handleApacheFlexSDKDownload " + e.message);
-             }
+            try
+            {
+                if (!overlaying)
+                {
+                    log(_viewResourceConstants.INFO_CREATING_FLEX_HOME);
+                }
+                _flexHomeDir = createFolder(_flexHome);
+                log(_viewResourceConstants.INFO_CREATING_TEMP_DIR);
+                _flexTemp = _flexHome + File.separator + "temp";
+                _flexTempDir = createFolder(_flexTemp);
+                updateActivityStep(_viewResourceConstants.STEP_CREATE_DIRECTORIES, StepItem.COMPLETE);
+                downloadApacheFlexSDK();
+            }
+            catch (e:Error)
+            {
+                updateActivityStep(_viewResourceConstants.STEP_CREATE_DIRECTORIES, StepItem.ERROR);
+                log(_viewResourceConstants.ERROR_UNABLE_TO_CREATE_TEMP_DIRECTORY);
+                abortInstallation(_viewResourceConstants.ERROR_UNABLE_TO_CREATE_TEMP_DIRECTORY);
+            }
+        }
 
-             updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_APACHE_FLEX_SDK, StepItem.COMPLETE);
+        protected function downloadApacheFlexSDK():void
+        {
+            updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_APACHE_FLEX_SDK, StepItem.ACTIVE);
 
-             updateActivityStep(_viewResourceConstants.STEP_VERIFY_FLEX_SDK, StepItem.ACTIVE);
+            try
+            {
+                log(_viewResourceConstants.INFO_DOWNLOADING_FLEX_SDK + APACHE_FLEX_BIN_DISTRO_URL);
+                _apacheFlexSDKCompressedFile = File.userDirectory.resolvePath(_flexTemp + File.separator + APACHE_FLEX_BIN_DISTRO_FILE);
+                copyOrDownload(APACHE_FLEX_BIN_DISTRO_URL, handleApacheFlexSDKDownload, _apacheFlexSDKCompressedFile, handleApacheFlexSDKDownloadError, nocache);
+            }
+            catch (e:Error)
+            {
+                updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_APACHE_FLEX_SDK, StepItem.ERROR);
+                log(_viewResourceConstants.ERROR_UNABLE_TO_CREATE_TEMP_DIRECTORY + "(error: " + e.message);
+                abortInstallation(_viewResourceConstants.ERROR_UNABLE_TO_CREATE_TEMP_DIRECTORY + "(error: " + e.message);
+            }
 
-             log(_viewResourceConstants.STEP_VERIFY_FLEX_SDK);
+        }
 
-             _md5CompareUtil.addEventListener(ProgressEvent.PROGRESS, md5VerificationProgressHandler);
-             _md5CompareUtil.verifyMD5(_apacheFlexSDKCompressedFile, APACHE_FLEX_BIN_DISTRO_PATH + APACHE_FLEX_BIN_DISTRO_FILE, uncompressApacheFlexSDK);
-         }
+        protected function handleApacheFlexSDKDownload(event:Event):void
+        {
+            try
+            {
+                writeFileToDirectory(_apacheFlexSDKCompressedFile, event.target.data);
+            }
+            catch (e:Error)
+            {
+                updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_APACHE_FLEX_SDK, StepItem.ERROR);
+                abortInstallation("handleApacheFlexSDKDownload " + e.message);
+            }
 
-         protected function md5VerificationProgressHandler(event:ProgressEvent):void
-         {
-             if (logProgressEvents)
-                 log("md5 progress " + event.bytesLoaded + "  " + event.bytesTotal, -1, false);
-             if (event.bytesTotal > 0)
-                 progressBar.percent = Math.round((event.bytesLoaded / event.bytesTotal) * 100);
-         }
+            updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_APACHE_FLEX_SDK, StepItem.COMPLETE);
 
-         protected function handleApacheFlexSDKDownloadError(event:* = null):void
-         {
-             updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_APACHE_FLEX_SDK, StepItem.ERROR);
-             log(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_FLEX_SDK);
-             abortInstallation(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_FLEX_SDK);
-         }
+            updateActivityStep(_viewResourceConstants.STEP_VERIFY_FLEX_SDK, StepItem.ACTIVE);
 
-         protected function uncompressApacheFlexSDK():void
-         {
-             if (!_md5CompareUtil.fileIsVerified)
-             {
-                 updateActivityStep(_viewResourceConstants.STEP_VERIFY_FLEX_SDK, StepItem.ERROR);
+            log(_viewResourceConstants.STEP_VERIFY_FLEX_SDK);
 
-                 log(_viewResourceConstants.ERROR_VERIFY_FLEX_SDK);
+            _md5CompareUtil.addEventListener(ProgressEvent.PROGRESS, md5VerificationProgressHandler);
+            _md5CompareUtil.verifyMD5(_apacheFlexSDKCompressedFile, APACHE_FLEX_BIN_DISTRO_PATH + APACHE_FLEX_BIN_DISTRO_FILE, uncompressApacheFlexSDK);
+        }
 
-                 abortInstallation(_viewResourceConstants.ERROR_VERIFY_FLEX_SDK);
-                 return;
-             }
-             else
-             {
-                 updateActivityStep(_viewResourceConstants.STEP_VERIFY_FLEX_SDK, StepItem.COMPLETE);
+        protected function md5VerificationProgressHandler(event:ProgressEvent):void
+        {
+            if (logProgressEvents)
+            {
+                log("md5 progress " + event.bytesLoaded + "  " + event.bytesTotal, -1, false);
+            }
+            if (event.bytesTotal > 0)
+            {
+                progressBar.percent = Math.round((event.bytesLoaded / event.bytesTotal) * 100);
+            }
+        }
 
-                 log(_viewResourceConstants.INFO_VERIFY_FLEX_SDK_DONE);
-             }
+        protected function handleApacheFlexSDKDownloadError(event:* = null):void
+        {
+            updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_APACHE_FLEX_SDK, StepItem.ERROR);
+            log(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_FLEX_SDK);
+            abortInstallation(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_FLEX_SDK);
+        }
 
-             updateActivityStep(_viewResourceConstants.STEP_UNZIP_FLEX_SDK, StepItem.ACTIVE);
+        protected function uncompressApacheFlexSDK():void
+        {
+            if (_md5CompareUtil.validMD5)
+            {
+                if (!_md5CompareUtil.fileIsVerified)
+                {
+                    updateActivityStep(_viewResourceConstants.STEP_VERIFY_FLEX_SDK, StepItem.ERROR);
 
-             try
-             {
-                 log(_viewResourceConstants.INFO_UNZIPPING + _apacheFlexSDKCompressedFile.nativePath);
+                    log(_viewResourceConstants.ERROR_VERIFY_FLEX_SDK);
 
-                 if (_os.isWindows())
-                 {
-                     unzip(_apacheFlexSDKCompressedFile, handleApacheFlexSDKZipFileUnzipComplete, handleApacheFlexSDKZipFileUnzipError);
-                 }
-                 else
-                 {
-                     untar(_apacheFlexSDKCompressedFile, _flexTempDir, handleApacheFlexSDKZipFileUnzipComplete, handleApacheFlexSDKZipFileUnzipError);
-                 }
-             }
-             catch (e:Error)
-             {
-                 updateActivityStep(_viewResourceConstants.STEP_UNZIP_FLEX_SDK, StepItem.ERROR);
-                 abortInstallation(_viewResourceConstants.STEP_UNZIP_FLEX_SDK + " " + e.message);
-             }
-         }
+                    abortInstallation(_viewResourceConstants.ERROR_VERIFY_FLEX_SDK);
+                    return;
+                }
+                else
+                {
+                    updateActivityStep(_viewResourceConstants.STEP_VERIFY_FLEX_SDK, StepItem.COMPLETE);
+                    log(_viewResourceConstants.INFO_VERIFY_FLEX_SDK_DONE);
+                }
+            }
+            else
+            {
+                updateActivityStep(_viewResourceConstants.STEP_VERIFY_FLEX_SDK, StepItem.COMPLETE);
 
-         protected function handleApacheFlexSDKZipFileUnzipComplete(event:Event):void
-         {
-             log(_viewResourceConstants.INFO_FINISHED_UNZIPPING + _apacheFlexSDKCompressedFile.nativePath);
-             updateActivityStep(_viewResourceConstants.STEP_UNZIP_FLEX_SDK, StepItem.COMPLETE);
+                log(_viewResourceConstants.INFO_VERIFY_FLEX_SDK_DONE);
+            }
 
-             if (_os.isWindows())
-             {
-                 if (usingXML)
-                     runInstallerScript();
-                 else
-                     downloadAIRRuntimeKitForWindows();
-             }
-             else
-             {
-                 if (!overlaying)
-                 {
-                     /* Copy all files from the unarchived directory to the root */
-                     var directory:File = _flexTempDir.resolvePath(APACHE_FLEX_BIN_DISTRO_FILE_SHORT);
-                     var files:Array = directory.getDirectoryListing();
-                     for each(var file:File in files)
-                     {
-                         file.copyTo(_flexHomeDir.resolvePath(file.name));
-                     }
-                 }
-                 if (usingXML)
-                 {
-                     runInstallerScript();
-                 }
-                 else
-                 {
-                     if (_os.isMac())
-                     {
-                         downloadAIRRuntimeKitForMac();
-                     }
-                     else
-                     {
-                         downloadAIRRuntimeKitForLinux();
-                     }
-                 }
-             }
-         }
+            updateActivityStep(_viewResourceConstants.STEP_UNZIP_FLEX_SDK, StepItem.ACTIVE);
+
+            try
+            {
+                log(_viewResourceConstants.INFO_UNZIPPING + _apacheFlexSDKCompressedFile.nativePath);
+
+                if (_os.isWindows())
+                {
+                    unzip(_apacheFlexSDKCompressedFile, handleApacheFlexSDKZipFileUnzipComplete, handleApacheFlexSDKZipFileUnzipError);
+                }
+                else
+                {
+                    untar(_apacheFlexSDKCompressedFile, _flexTempDir, handleApacheFlexSDKZipFileUnzipComplete, handleApacheFlexSDKZipFileUnzipError);
+                }
+            }
+            catch (e:Error)
+            {
+                updateActivityStep(_viewResourceConstants.STEP_UNZIP_FLEX_SDK, StepItem.ERROR);
+                abortInstallation(_viewResourceConstants.STEP_UNZIP_FLEX_SDK + " " + e.message);
+            }
+        }
+
+        protected function handleApacheFlexSDKZipFileUnzipComplete(event:Event):void
+        {
+            log(_viewResourceConstants.INFO_FINISHED_UNZIPPING + _apacheFlexSDKCompressedFile.nativePath);
+            updateActivityStep(_viewResourceConstants.STEP_UNZIP_FLEX_SDK, StepItem.COMPLETE);
+
+            if (_os.isWindows())
+            {
+                if (usingXML)
+                {
+                    runInstallerScript();
+                }
+                else
+                {
+                    downloadAIRRuntimeKitForWindows();
+                }
+            }
+            else
+            {
+                if (!overlaying)
+                {
+                    /* Copy all files from the unarchived directory to the root */
+                    var directory:File = _flexTempDir.resolvePath(APACHE_FLEX_BIN_DISTRO_FILE_SHORT);
+                    var files:Array = directory.getDirectoryListing();
+                    for each(var file:File in files)
+                    {
+                        file.copyTo(_flexHomeDir.resolvePath(file.name));
+                    }
+                }
+                if (usingXML)
+                {
+                    runInstallerScript();
+                }
+                else
+                {
+                    if (_os.isMac())
+                    {
+                        downloadAIRRuntimeKitForMac();
+                    }
+                    else
+                    {
+                        downloadAIRRuntimeKitForLinux();
+                    }
+                }
+            }
+        }
+
+        protected function handleApacheFlexSDKZipFileUnzipError(error:ErrorEvent = null):void
+        {
+            updateActivityStep(_viewResourceConstants.STEP_UNZIP_FLEX_SDK, StepItem.ERROR);
+            abortInstallation(_viewResourceConstants.STEP_UNZIP_FLEX_SDK + " " + error.toString());
+        }
+
+        protected function runInstallerScript():void
+        {
+            ant = new Ant();
+            ant.output = output;
+
+            var file:File;
+            if (installOverride != "")
+            {
+                file = new File(installOverride);
+            }
+            else if (overlaying)
+            {
+                var directory:File = _flexTempDir.resolvePath(APACHE_FLEX_BIN_DISTRO_FILE_SHORT);
+                if (_os.isWindows())
+                {
+                    file = _flexTempDir.resolvePath("installer.xml");
+                }
+                else
+                {
+                    file = directory.resolvePath("installer.xml");
+                }
+            }
+            else
+            {
+                file = _flexHomeDir.resolvePath("installer.xml");
+            }
+            addEventListener(Event.ENTER_FRAME, enterFrameHandler);
+            var context:Object = {installer: true};
+            if (usingDownloadCache)
+            {
+                context["usingDownloadCache"] = usingDownloadCache;
+                context["downloadCacheFolder"] = downloadCacheFolder;
+            }
+            if (configOverride != "")
+            {
+                context["xml.properties"] = configOverride;
+            }
+            if (resourceManager.localeChain.length > 1)
+            {
+                context["bundle"] = resourceManager.localeChain[0];
+            }
+            for (var p:String in licensePropertyMap)
+            {
+                if (InstallerComponentVO(licensePropertyMap[p]).selected)
+                {
+                    context[p] = true;
+                }
+            }
+            for (p in additionalProps)
+            {
+                context[p] = additionalProps[p];
+            }
 
-         protected function handleApacheFlexSDKZipFileUnzipError(error:ErrorEvent = null):void
-         {
-             updateActivityStep(_viewResourceConstants.STEP_UNZIP_FLEX_SDK, StepItem.ERROR);
-             abortInstallation(_viewResourceConstants.STEP_UNZIP_FLEX_SDK + " " + error.toString());
-         }
+            context["air.sdk.version"] = AIR_VERSION;
+            if (airVersion.selectedItem.versionID)
+            {
+                context["air.sdk.versionID"] = airVersion.selectedItem.versionID;
+            }
+            context["air.sdk.url.path"] = airVersion.selectedItem.path;
+            context["air.sdk.url.file"] = airVersion.selectedItem.file;
+            context["flash.sdk.version"] = FLASH_PLAYER_VERSION;
+            if (flashPlayerVersion.selectedItem.versionID)
+            {
+                context["flash.sdk.versionID"] = flashPlayerVersion.selectedItem.versionID;
+            }
+            if (debugMode)
+            {
+                context["verbose"] = true;
+            }
+            if (flashPlayerVersion.selectedItem.path)
+            {
+                context["flash.sdk.url.path"] = flashPlayerVersion.selectedItem.path;
+                context["flash.sdk.url.file"] = flashPlayerVersion.selectedItem.file;
+            }
 
-         protected function runInstallerScript():void
-         {
-             ant = new Ant();
-             ant.output = output;
+            if (file.exists && !ant.processXMLFile(file, context, true))
+            {
+                ant.addEventListener(Event.COMPLETE, completeHandler);
+                ant.addEventListener(ProgressEvent.PROGRESS, progressEventHandler);
+            }
+            else
+            {
+                completeHandler(null);
+            }
+        }
 
-             var file:File;
-             if (installOverride != "")
+        private function progressEventHandler(event:ProgressEvent):void
+        {
+            if (logProgressEvents)
+            {
+                log("progress " + event.bytesLoaded + "  " + event.bytesTotal, -1, false);
+            }
+            if (event.bytesTotal > 0)
+            {
+                progressBar.percent = Math.round((event.bytesLoaded / event.bytesTotal) * 100);
+            }
+            /*
+             if (ant.progressClass is Copy)
              {
-                 file = new File(installOverride);
+             progressBar.label = getLocalizedString(progressLabels, "Copy");
              }
-             else if (overlaying)
+             else if (ant.progressClass is Get)
              {
-                 var directory:File = _flexTempDir.resolvePath(APACHE_FLEX_BIN_DISTRO_FILE_SHORT);
-                 if (_os.isWindows())
-                 {
-                     file = _flexTempDir.resolvePath("installer.xml");
-                 }
-                 else
-                 {
-                     file = directory.resolvePath("installer.xml");
-                 }
+             progressBar.label = getLocalizedString(progressLabels, "Get");
              }
-             else
+             else if (ant.progressClass is Checksum)
              {
-                 file = _flexHomeDir.resolvePath("installer.xml");
+             progressBar.label = getLocalizedString(progressLabels, "Checksum");
              }
-             addEventListener(Event.ENTER_FRAME, enterFrameHandler);
-             var context:Object = {installer: true};
-             if (usingDownloadCache)
-             {
-                 context["usingDownloadCache"] = usingDownloadCache;
-                 context["downloadCacheFolder"] = downloadCacheFolder;
-             }
-             if (configOverride != "")
-             {
-                 context["xml.properties"] = configOverride;
-             }
-             if (resourceManager.localeChain.length > 1)
-             {
-                 context["bundle"] = resourceManager.localeChain[0];
-             }
-             for (var p:String in licensePropertyMap)
-             {
-                 if (InstallerComponentVO(licensePropertyMap[p]).selected)
-                     context[p] = true;
-             }
-             for (p in additionalProps)
-                 context[p] = additionalProps[p];
+             */
+        }
 
-             context["air.sdk.version"] = AIR_VERSION;
-             if (airVersion.selectedItem.versionID)
-                 context["air.sdk.versionID"] = airVersion.selectedItem.versionID;
-             context["air.sdk.url.path"] = airVersion.selectedItem.path;
-             context["air.sdk.url.file"] = airVersion.selectedItem.file;
-             context["flash.sdk.version"] = FLASH_PLAYER_VERSION;
-             if (flashPlayerVersion.selectedItem.versionID)
-                 context["flash.sdk.versionID"] = flashPlayerVersion.selectedItem.versionID;
-             if (debugMode)
-                 context["verbose"] = true;
-             if (flashPlayerVersion.selectedItem.path)
-             {
-                 context["flash.sdk.url.path"] = flashPlayerVersion.selectedItem.path;
-                 context["flash.sdk.url.file"] = flashPlayerVersion.selectedItem.file;
-             }
+        private function completeHandler(event:Event):void
+        {
+            if (Ant.currentAnt && !Ant.currentAnt.project.status)
+            {
+                var msg:String = Ant.currentAnt.project.failureMessage;
+                log(msg ? msg : "no failure message provided");
+                if (currentStep > 0)
+                {
+                    updateActivityStep(stepLabels[currentStep - 1], StepItem.ERROR);
+                }
+            }
+            else if (currentStep == stepLabels.length && currentStep > 0)
+            {
+                updateActivityStep(stepLabels[currentStep - 1], StepItem.COMPLETE);
+            }
 
-             if (file.exists && !ant.processXMLFile(file, context, true))
-             {
-                 ant.addEventListener(Event.COMPLETE, completeHandler);
-                 ant.addEventListener(ProgressEvent.PROGRESS, progressEventHandler);
-             }
-             else
-                 completeHandler(null);
-         }
+            if (Ant.currentAnt)
+            {
+                if (Ant.currentAnt.project.status)
+                {
+                    tracker.trackInstallerSuccess(APACHE_FLEX_BIN_DISTRO_VERSION_DISPLAY, APACHE_FLEX_BIN_DISTRO_VERSION, _os.os);
+                }
+                if (Ant.currentAnt.project.failureMessage)
+                {
+                    cleanup(!Ant.currentAnt.project.status, "&info=" + escape(Ant.currentAnt.project.failureMessage));
+                }
+                else
+                {
+                    cleanup(!Ant.currentAnt.project.status);
+                }
+            }
+            else
+            {
+                cleanup();
+            }
+        }
 
-         private function progressEventHandler(event:ProgressEvent):void
-         {
-             if (logProgressEvents)
-                 log("progress " + event.bytesLoaded + "  " + event.bytesTotal, -1, false);
-             if (event.bytesTotal > 0)
-                 progressBar.percent = Math.round((event.bytesLoaded / event.bytesTotal) * 100);
-             /*
-              if (ant.progressClass is Copy)
-              {
-              progressBar.label = getLocalizedString(progressLabels, "Copy");
-              }
-              else if (ant.progressClass is Get)
-              {
-              progressBar.label = getLocalizedString(progressLabels, "Get");
-              }
-              else if (ant.progressClass is Checksum)
-              {
-              progressBar.label = getLocalizedString(progressLabels, "Checksum");
-              }
-              */
-         }
+        private var ant:Ant;
 
-         private function completeHandler(event:Event):void
-         {
-             if (Ant.currentAnt && !Ant.currentAnt.project.status)
-             {
-                 var msg:String = Ant.currentAnt.project.failureMessage;
-                 log(msg ? msg : "no failure message provided");
-                 if (currentStep > 0)
-                     updateActivityStep(stepLabels[currentStep - 1], StepItem.ERROR);
-             }
-             else if (currentStep == stepLabels.length && currentStep > 0)
-                 updateActivityStep(stepLabels[currentStep - 1], StepItem.COMPLETE);
+        private function output(s:String):void
+        {
+            var isPublic:Boolean = false;
+            var skipLog:Boolean = !debugMode;
+            if (s.indexOf(":") != -1 && s.charAt(0) == "\n")
+            {
+                // target output is a newline then the target name then a colon
+                if (currentStep < stepLabels.length && "\n" + stepIDs[currentStep] + ":" == s)
+                {
+                    if (currentStep > 0)
+                    {
+                        updateActivityStep(stepLabels[currentStep - 1], StepItem.COMPLETE);
+                    }
+                    if (currentStep < stepLabels.length)
+                    {
+                        updateActivityStep(stepLabels[currentStep++], StepItem.ACTIVE);
+                    }
+                }
+                isPublic = false;
+            }
+            else if (s.indexOf("[echo] ") != -1)
+            {
+                s = s.substr(s.indexOf("[echo] ") + 7);
+                isPublic = true;
+                skipLog = false;
+            }
+            else if (s.indexOf("[fail] ") != -1)
+            {
+                s = s.substr(s.indexOf("[fail] ") + 7);
+                isPublic = true;
+                skipLog = false;
+            }
+            log(s, -1, isPublic, skipLog);
+        }
 
-             if (Ant.currentAnt)
-             {
-                 if (Ant.currentAnt.project.status)
-                     tracker.trackInstallerSuccess(APACHE_FLEX_BIN_DISTRO_VERSION_DISPLAY, APACHE_FLEX_BIN_DISTRO_VERSION, _os.os);
-                 if (Ant.currentAnt.project.failureMessage)
-                     cleanup(!Ant.currentAnt.project.status, "&info=" + escape(Ant.currentAnt.project.failureMessage));
-                 else
-                     cleanup(!Ant.currentAnt.project.status);
-             }
-             else
-             {
-                 cleanup();
-             }
-         }
+        private function enterFrameHandler(event:Event):void
+        {
+            ant.doCallback();
+        }
 
-         private var ant:Ant;
+        protected function downloadAIRRuntimeKitForWindows():void
+        {
+            updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK, StepItem.ACTIVE);
 
-         private function output(s:String):void
-         {
-             var isPublic:Boolean = false;
-             var skipLog:Boolean = !debugMode;
-             if (s.indexOf(":") != -1 && s.charAt(0) == "\n")
-             {
-                 // target output is a newline then the target name then a colon
-                 if (currentStep < stepLabels.length && "\n" + stepIDs[currentStep] + ":" == s)
-                 {
-                     if (currentStep > 0)
-                         updateActivityStep(stepLabels[currentStep - 1], StepItem.COMPLETE);
-                     if (currentStep < stepLabels.length)
-                         updateActivityStep(stepLabels[currentStep++], StepItem.ACTIVE);
-                 }
-                 isPublic = false;
-             }
-             else if (s.indexOf("[echo] ") != -1)
-             {
-                 s = s.substr(s.indexOf("[echo] ") + 7);
-                 isPublic = true;
-                 skipLog = false;
-             }
-             else if (s.indexOf("[fail] ") != -1)
-             {
-                 s = s.substr(s.indexOf("[fail] ") + 7);
-                 isPublic = true;
-                 skipLog = false;
-             }
-             log(s, -1, isPublic, skipLog);
-         }
+            try
+            {
+                log(_viewResourceConstants.INFO_DOWNLOADING_AIR_RUNTIME_KIT_WINDOWS + ADOBE_AIR_SDK_WIN_URL);
+                _adobeAIRSDKZipFile = File.userDirectory.resolvePath(_flexTemp + File.separator + ADOBE_AIR_SDK_WIN_FILE);
+                copyOrDownload(ADOBE_AIR_SDK_WIN_URL, handleAIRSDKDownload, _adobeAIRSDKZipFile, handleAIRSDKDownloadError);
+            }
+            catch (e:Error)
+            {
+                updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK, StepItem.ERROR);
+                abortInstallation();
+            }
+        }
 
-         private function enterFrameHandler(event:Event):void
-         {
-             ant.doCallback();
-         }
+        protected function downloadAIRRuntimeKitForMac():void
+        {
+            updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK, StepItem.ACTIVE);
 
-         protected function downloadAIRRuntimeKitForWindows():void
-         {
-             updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK, StepItem.ACTIVE);
+            try
+            {
+                log(_viewResourceConstants.INFO_DOWNLOADING_AIR_RUNTIME_KIT_MAC + ADOBE_AIR_SDK_MAC_URL);
+                _adobeAIRSDKZipFile = File.userDirectory.resolvePath(_flexTemp + File.separator + ADOBE_AIR_SDK_MAC_FILE);
+                copyOrDownload(ADOBE_AIR_SDK_MAC_URL, handleAIRSDKDownload, _adobeAIRSDKZipFile, handleAIRSDKDownloadError);
+            }
+            catch (e:Error)
+            {
+                updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK, StepItem.ERROR);
+                abortInstallation();
+            }
+        }
 
-             try
-             {
-                 log(_viewResourceConstants.INFO_DOWNLOADING_AIR_RUNTIME_KIT_WINDOWS + ADOBE_AIR_SDK_WIN_URL);
-                 _adobeAIRSDKZipFile = File.userDirectory.resolvePath(_flexTemp + File.separator + ADOBE_AIR_SDK_WIN_FILE);
-                 copyOrDownload(ADOBE_AIR_SDK_WIN_URL, handleAIRSDKDownload, _adobeAIRSDKZipFile, handleAIRSDKDownloadError);
-             }
-             catch (e:Error)
-             {
-                 updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK, StepItem.ERROR);
-                 abortInstallation();
-             }
-         }
+        protected function downloadAIRRuntimeKitForLinux():void
+        {
+            updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK, StepItem.ACTIVE);
 
-         protected function downloadAIRRuntimeKitForMac():void
-         {
-             updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK, StepItem.ACTIVE);
+            try
+            {
+                log(_viewResourceConstants.INFO_DOWNLOADING_AIR_RUNTIME_KIT_MAC + ADOBE_AIR_SDK_LINUX_URL);
+                _adobeAIRSDKZipFile = File.userDirectory.resolvePath(_flexTemp + File.separator + ADOBE_AIR_SDK_LINUX_FILE);
+                copyOrDownload(ADOBE_AIR_SDK_LINUX_URL, handleAIRSDKDownload, _adobeAIRSDKZipFile, handleAIRSDKDownloadError);
+            }
+            catch (e:Error)
+            {
+                updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK, StepItem.ERROR);
+                abortInstallation();
+            }
+        }
 
-             try
-             {
-                 log(_viewResourceConstants.INFO_DOWNLOADING_AIR_RUNTIME_KIT_MAC + ADOBE_AIR_SDK_MAC_URL);
-                 _adobeAIRSDKZipFile = File.userDirectory.resolvePath(_flexTemp + File.separator + ADOBE_AIR_SDK_MAC_FILE);
-                 copyOrDownload(ADOBE_AIR_SDK_MAC_URL, handleAIRSDKDownload, _adobeAIRSDKZipFile, handleAIRSDKDownloadError);
-             }
-             catch (e:Error)
-             {
-                 updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK, StepItem.ERROR);
-                 abortInstallation();
-             }
-         }
+        protected function handleAIRSDKDownload(event:Event):void
+        {
+            try
+            {
+                writeFileToDirectory(_adobeAIRSDKZipFile, event.target.data);
+            }
+            catch (e:Error)
+            {
+                updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK, StepItem.ERROR);
+                abortInstallation();
+            }
 
-         protected function downloadAIRRuntimeKitForLinux():void
-         {
-             updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK, StepItem.ACTIVE);
+            updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK, StepItem.COMPLETE);
 
-             try
-             {
-                 log(_viewResourceConstants.INFO_DOWNLOADING_AIR_RUNTIME_KIT_MAC + ADOBE_AIR_SDK_LINUX_URL);
-                 _adobeAIRSDKZipFile = File.userDirectory.resolvePath(_flexTemp + File.separator + ADOBE_AIR_SDK_LINUX_FILE);
-                 copyOrDownload(ADOBE_AIR_SDK_LINUX_URL, handleAIRSDKDownload, _adobeAIRSDKZipFile, handleAIRSDKDownloadError);
-             }
-             catch (e:Error)
-             {
-                 updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK, StepItem.ERROR);
-                 abortInstallation();
-             }
-         }
+            unzipAdobeAIRSDK();
+        }
 
-         protected function handleAIRSDKDownload(event:Event):void
-         {
-             try
-             {
-                 writeFileToDirectory(_adobeAIRSDKZipFile, event.target.data);
-             }
-             catch (e:Error)
-             {
-                 updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK, StepItem.ERROR);
-                 abortInstallation();
-             }
+        protected function handleAIRSDKDownloadError(error:* = null):void
+        {
+            updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK, StepItem.ERROR);
+            log(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_AIR_SDK);
+            abortInstallation();
+        }
 
-             updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK, StepItem.COMPLETE);
+        protected function unzipAdobeAIRSDK():void
+        {
+            updateActivityStep(_viewResourceConstants.STEP_UNZIP_AIR_RUNTIME_KIT, StepItem.ACTIVE);
 
-             unzipAdobeAIRSDK();
-         }
+            try
+            {
+                if (_os.isWindows())
+                {
+                    unzipAdobeAIRSDKWindows()
+                }
+                else
+                {
+                    unzipAdobeAIRSDKMac();
+                }
+            }
+            catch (e:Error)
+            {
+                updateActivityStep(_viewResourceConstants.STEP_UNZIP_AIR_RUNTIME_KIT, StepItem.ERROR);
+                abortInstallation();
+            }
+        }
 
-         protected function handleAIRSDKDownloadError(error:* = null):void
-         {
-             updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK, StepItem.ERROR);
-             log(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_AIR_SDK);
-             abortInstallation();
-         }
+        protected function unzipAdobeAIRSDKWindows():void
+        {
+            log(_viewResourceConstants.INFO_UNZIPPING + _adobeAIRSDKZipFile.nativePath);
+            unzip(_adobeAIRSDKZipFile, handleAdobeAIRSDKWinZipFileUnzipComplete, handleAdobeAIRSDKWinZipFileUnzipError);
+        }
 
-         protected function unzipAdobeAIRSDK():void
-         {
-             updateActivityStep(_viewResourceConstants.STEP_UNZIP_AIR_RUNTIME_KIT, StepItem.ACTIVE);
+        protected function unzipAdobeAIRSDKMac():void
+        {
+            if (NativeProcess.isSupported)
+            {
+                untar(_adobeAIRSDKZipFile, _flexHomeDir, handleAdobeAIRSDKMacUntarComplete, handleAdobeAIRSDKMacUntarError);
+            }
+            else
+            {
+                log(_viewResourceConstants.ERROR_NATIVE_PROCESS_NOT_SUPPORTED);
+                updateActivityStep(_viewResourceConstants.STEP_UNZIP_AIR_RUNTIME_KIT, StepItem.ERROR);
+            }
+        }
 
-             try
-             {
-                 if (_os.isWindows())
-                 {
-                     unzipAdobeAIRSDKWindows()
-                 }
-                 else
-                 {
-                     unzipAdobeAIRSDKMac();
-                 }
-             }
-             catch (e:Error)
-             {
-                 updateActivityStep(_viewResourceConstants.STEP_UNZIP_AIR_RUNTIME_KIT, StepItem.ERROR);
-                 abortInstallation();
-             }
-         }
+        protected function handleAdobeAIRSDKMacUntarError(error:ProgressEvent = null):void
+        {
+            updateActivityStep(_viewResourceConstants.STEP_UNZIP_AIR_RUNTIME_KIT, StepItem.ERROR);
+            abortInstallation();
+        }
 
-         protected function unzipAdobeAIRSDKWindows():void
-         {
-             log(_viewResourceConstants.INFO_UNZIPPING + _adobeAIRSDKZipFile.nativePath);
-             unzip(_adobeAIRSDKZipFile, handleAdobeAIRSDKWinZipFileUnzipComplete, handleAdobeAIRSDKWinZipFileUnzipError);
-         }
+        protected function handleAdobeAIRSDKMacUntarComplete(event:Event):void
+        {
+            updateActivityStep(_viewResourceConstants.STEP_UNZIP_AIR_RUNTIME_KIT, StepItem.COMPLETE);
+            log(_viewResourceConstants.INFO_FINISHED_UNTARING + _adobeAIRSDKZipFile.nativePath);
+            downloadPlayerGlobalSWC();
+        }
 
-         protected function unzipAdobeAIRSDKMac():void
-         {
-             if (NativeProcess.isSupported)
-             {
-                 untar(_adobeAIRSDKZipFile, _flexHomeDir, handleAdobeAIRSDKMacUntarComplete, handleAdobeAIRSDKMacUntarError);
-             }
-             else
-             {
-                 log(_viewResourceConstants.ERROR_NATIVE_PROCESS_NOT_SUPPORTED);
-                 updateActivityStep(_viewResourceConstants.STEP_UNZIP_AIR_RUNTIME_KIT, StepItem.ERROR);
-             }
-         }
+        protected function handleAdobeAIRSDKWinZipFileUnzipComplete(event:Event):void
+        {
+            updateActivityStep(_viewResourceConstants.STEP_UNZIP_AIR_RUNTIME_KIT, StepItem.COMPLETE);
+            log(_viewResourceConstants.INFO_FINISHED_UNZIPPING + _adobeAIRSDKZipFile.nativePath);
+            downloadPlayerGlobalSWC();
+        }
 
-         protected function handleAdobeAIRSDKMacUntarError(error:ProgressEvent = null):void
-         {
-             updateActivityStep(_viewResourceConstants.STEP_UNZIP_AIR_RUNTIME_KIT, StepItem.ERROR);
-             abortInstallation();
-         }
+        protected function handleAdobeAIRSDKWinZipFileUnzipError(error:ErrorEvent = null):void
+        {
+            updateActivityStep(_viewResourceConstants.STEP_UNZIP_AIR_RUNTIME_KIT, StepItem.ERROR);
+        }
 
-         protected function handleAdobeAIRSDKMacUntarComplete(event:Event):void
-         {
-             updateActivityStep(_viewResourceConstants.STEP_UNZIP_AIR_RUNTIME_KIT, StepItem.COMPLETE);
-             log(_viewResourceConstants.INFO_FINISHED_UNTARING + _adobeAIRSDKZipFile.nativePath);
-             downloadPlayerGlobalSWC();
-         }
+        protected function downloadPlayerGlobalSWC():void
+        {
+            updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_FLASH_PLAYER_GLOBAL_SWC, StepItem.ACTIVE);
 
-         protected function handleAdobeAIRSDKWinZipFileUnzipComplete(event:Event):void
-         {
-             updateActivityStep(_viewResourceConstants.STEP_UNZIP_AIR_RUNTIME_KIT, StepItem.COMPLETE);
-             log(_viewResourceConstants.INFO_FINISHED_UNZIPPING + _adobeAIRSDKZipFile.nativePath);
-             downloadPlayerGlobalSWC();
-         }
+            try
+            {
+                log(_viewResourceConstants.INFO_INSTALLING_PLAYERGLOBAL_SWC + ADOBE_FB_GLOBALPLAYER_SWC_URL);
+                _fbGlobalPlayerDir = createFolder(_flexHome + File.separator + "frameworks" + File.separator + "libs" + File.separator + "player"
+                        + File.separator + FLASH_PLAYER_VERSION);
+                _fbGlobalPlayerFile = File.userDirectory.resolvePath(_fbGlobalPlayerDir.nativePath + File.separator + "playerglobal.swc");
+                copyOrDownload(ADOBE_FB_GLOBALPLAYER_SWC_URL, handlePlayerGlobalDownload, _fbGlobalPlayerFile, handlePlayerGlobalDownloadError);
+            }
+            catch (e:Error)
+            {
+                updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_FLASH_PLAYER_GLOBAL_SWC, StepItem.ERROR);
+                abortInstallation();
+            }
+        }
 
-         protected function handleAdobeAIRSDKWinZipFileUnzipError(error:ErrorEvent = null):void
-         {
-             updateActivityStep(_viewResourceConstants.STEP_UNZIP_AIR_RUNTIME_KIT, StepItem.ERROR);
-         }
+        protected function handlePlayerGlobalDownload(event:Event):void
+        {
+            try
+            {
+                var playerGlobalFile:File = File.userDirectory.resolvePath(_fbGlobalPlayerDir.nativePath + File.separator + "playerglobal.swc");
+                writeFileToDirectory(playerGlobalFile, event.target.data);
+            }
+            catch (e:Error)
+            {
+                updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_FLASH_PLAYER_GLOBAL_SWC, StepItem.ERROR);
+                abortInstallation();
+            }
+            updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_FLASH_PLAYER_GLOBAL_SWC, StepItem.COMPLETE);
+            copyConfigFiles();
+        }
 
-         protected function downloadPlayerGlobalSWC():void
-         {
-             updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_FLASH_PLAYER_GLOBAL_SWC, StepItem.ACTIVE);
+        protected function handlePlayerGlobalDownloadError(event:ErrorEvent = null):void
+        {
+            updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_FLASH_PLAYER_GLOBAL_SWC, StepItem.ERROR);
+            log(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_FLASH_PLAYER_SWC);
+            abortInstallation();
+        }
 
-             try
-             {
-                 log(_viewResourceConstants.INFO_INSTALLING_PLAYERGLOBAL_SWC + ADOBE_FB_GLOBALPLAYER_SWC_URL);
-                 _fbGlobalPlayerDir = createFolder(_flexHome + File.separator + "frameworks" + File.separator + "libs" + File.separator + "player"
-                 + File.separator + FLASH_PLAYER_VERSION);
-                 _fbGlobalPlayerFile = File.userDirectory.resolvePath(_fbGlobalPlayerDir.nativePath + File.separator + "playerglobal.swc");
-                 copyOrDownload(ADOBE_FB_GLOBALPLAYER_SWC_URL, handlePlayerGlobalDownload, _fbGlobalPlayerFile, handlePlayerGlobalDownloadError);
-             }
-             catch (e:Error)
-             {
-                 updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_FLASH_PLAYER_GLOBAL_SWC, StepItem.ERROR);
-                 abortInstallation();
-             }
-         }
+        protected function changeConfig(frameworksDir:File, file:File, flashPlayerVersion:String, swfVersion:String):void
+        {
+            if (isValidConfigFile(file))
+            {
+                var configFile:FileStream = new FileStream();
+                configFile.open(file, FileMode.READ);
+                var contents:String = configFile.readMultiByte(configFile.bytesAvailable, "utf-8");
+                var playerVersion:RegExp = /<target-player>\d\d\.\d<\/target-player>/;
+                contents = contents.replace(playerVersion, "<target-player>" + flashPlayerVersion + "<\/target-player>");
+                var playerSwfVersion:RegExp = /<swf-version>\d\d<\/swf-version>/;
+                contents = contents.replace(playerSwfVersion, "<swf-version>" + swfVersion + "<\/swf-version>");
+                configFile.close();
+                configFile.open(file, FileMode.WRITE);
+                configFile.writeMultiByte(contents, "utf-8");
+                var copyToFile:File = frameworksDir.resolvePath(file.name);
+                configFile.close();
+                file.copyTo(copyToFile, true);
+            }
+        }
 
-         protected function handlePlayerGlobalDownload(event:Event):void
-         {
-             try
-             {
-                 var playerGlobalFile:File = File.userDirectory.resolvePath(_fbGlobalPlayerDir.nativePath + File.separator + "playerglobal.swc");
-                 writeFileToDirectory(playerGlobalFile, event.target.data);
-             }
-             catch (e:Error)
-             {
-                 updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_FLASH_PLAYER_GLOBAL_SWC, StepItem.ERROR);
-                 abortInstallation();
-             }
-             updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_FLASH_PLAYER_GLOBAL_SWC, StepItem.COMPLETE);
-             copyConfigFiles();
-         }
+        protected function copyConfigFiles():void
+        {
+            var aborted:Boolean = false;
 
-         protected function handlePlayerGlobalDownloadError(event:ErrorEvent = null):void
-         {
-             updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_FLASH_PLAYER_GLOBAL_SWC, StepItem.ERROR);
-             log(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_FLASH_PLAYER_SWC);
-             abortInstallation();
-         }
+            updateActivityStep(_viewResourceConstants.STEP_INSTALL_CONFIG_FILES, StepItem.ACTIVE);
 
-         protected function changeConfig(frameworksDir:File, file:File, flashPlayerVersion:String, swfVersion:String):void
-         {
-             if (isValidConfigFile(file))
-             {
-                 var configFile:FileStream = new FileStream();
-                 configFile.open(file, FileMode.READ);
-                 var contents:String = configFile.readMultiByte(configFile.bytesAvailable, "utf-8");
-                 var playerVersion:RegExp = /<target-player>\d\d\.\d<\/target-player>/;
-                 contents = contents.replace(playerVersion, "<target-player>" + flashPlayerVersion + "<\/target-player>");
-                 var playerSwfVersion:RegExp = /<swf-version>\d\d<\/swf-version>/;
-                 contents = contents.replace(playerSwfVersion, "<swf-version>" + swfVersion + "<\/swf-version>");
-                 configFile.close();
-                 configFile.open(file, FileMode.WRITE);
-                 configFile.writeMultiByte(contents, "utf-8");
-                 var copyToFile:File = frameworksDir.resolvePath(file.name);
-                 configFile.close();
-                 file.copyTo(copyToFile, true);
-             }
-         }
+            try
+            {
+                //Config files
+                var configFilesDir:File = File.userDirectory.resolvePath(_flexHome + File.separator + "ide" + File.separator + "flashbuilder" + File.separator
+                        + "config");
+                var configFiles:Array = configFilesDir.getDirectoryListing();
+                var flexHomeFrameworksDir:File = File.userDirectory.resolvePath(_flexHome + File.separator + "frameworks");
+                log(_viewResourceConstants.INFO_INSTALLING_CONFIG_FILES);
 
-         protected function copyConfigFiles():void
-         {
-             var aborted:Boolean = false;
+                for each (var file:File in configFiles)
+                {
+                    changeConfig(flexHomeFrameworksDir, file, FLASH_PLAYER_VERSION, FLASH_PLAYER_SWF_VERSION);
+                }
 
-             updateActivityStep(_viewResourceConstants.STEP_INSTALL_CONFIG_FILES, StepItem.ACTIVE);
+                file = File.userDirectory.resolvePath(_flexHome + File.separator + "flex-sdk-description.xml");
+                var descriptionFile:FileStream = new FileStream();
+                descriptionFile.open(file, FileMode.READ);
+                var contents:String = descriptionFile.readMultiByte(descriptionFile.bytesAvailable, "utf-8");
+                var description:RegExp = /<name>[^<]*<\/name>/;
+                contents = contents.replace(description, "<name>Apache Flex " + APACHE_FLEX_BIN_DISTRO_VERSION + " FP " + FLASH_PLAYER_VERSION + " AIR " + AIR_VERSION + " en_US</name>");
+                descriptionFile.close();
+                descriptionFile.open(file, FileMode.WRITE);
+                descriptionFile.writeMultiByte(contents, "utf-8");
+                descriptionFile.close();
+            }
+            catch (e:Error)
+            {
+                updateActivityStep(_viewResourceConstants.STEP_INSTALL_CONFIG_FILES, StepItem.ERROR);
+                log(_viewResourceConstants.ERROR_UNABLE_TO_INSTALL_CONFIG_FILES);
+                abortInstallation();
+                aborted = true;
+            }
 
-             try
-             {
-                 //Config files
-                 var configFilesDir:File = File.userDirectory.resolvePath(_flexHome + File.separator + "ide" + File.separator + "flashbuilder" + File.separator
-                 + "config");
-                 var configFiles:Array = configFilesDir.getDirectoryListing();
-                 var flexHomeFrameworksDir:File = File.userDirectory.resolvePath(_flexHome + File.separator + "frameworks");
-                 log(_viewResourceConstants.INFO_INSTALLING_CONFIG_FILES);
+            if (!aborted)
+            {
+                updateActivityStep(_viewResourceConstants.STEP_INSTALL_CONFIG_FILES, StepItem.COMPLETE);
+                downloadSwfObject();
+            }
+        }
 
-                 for each (var file:File in configFiles)
-                 {
-                     changeConfig(flexHomeFrameworksDir, file, FLASH_PLAYER_VERSION, FLASH_PLAYER_SWF_VERSION);
-                 }
+        protected function downloadSwfObject():void
+        {
+            updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_SWFOBJECT, StepItem.ACTIVE);
 
-                 file = File.userDirectory.resolvePath(_flexHome + File.separator + "flex-sdk-description.xml");
-                 var descriptionFile:FileStream = new FileStream();
-                 descriptionFile.open(file, FileMode.READ);
-                 var contents:String = descriptionFile.readMultiByte(descriptionFile.bytesAvailable, "utf-8");
-                 var description:RegExp = /<name>[^<]*<\/name>/;
-                 contents = contents.replace(description, "<name>Apache Flex " + APACHE_FLEX_BIN_DISTRO_VERSION + " FP " + FLASH_PLAYER_VERSION + " AIR " + AIR_VERSION + " en_US</name>");
-                 descriptionFile.close();
-                 descriptionFile.open(file, FileMode.WRITE);
-                 descriptionFile.writeMultiByte(contents, "utf-8");
-                 descriptionFile.close();
-             }
-             catch (e:Error)
-             {
-                 updateActivityStep(_viewResourceConstants.STEP_INSTALL_CONFIG_FILES, StepItem.ERROR);
-                 log(_viewResourceConstants.ERROR_UNABLE_TO_INSTALL_CONFIG_FILES);
-                 abortInstallation();
-                 aborted = true;
-             }
+            try
+            {
+                log(StringUtil.substitute(_viewResourceConstants.INFO_DOWNLOADING_FILE_FROM, [SWF_OBJECT_FILE, SWF_OBJECT_URL]));
+                copyOrDownload(SWF_OBJECT_URL + SWF_OBJECT_FILE, handlSWFObjectDownload, null, handleSWFObjectDownloadError);
+            }
+            catch (e:Error)
+            {
+                updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_SWFOBJECT, StepItem.ERROR);
+                abortInstallation();
+            }
+        }
 
-             if (!aborted)
-             {
-                 updateActivityStep(_viewResourceConstants.STEP_INSTALL_CONFIG_FILES, StepItem.COMPLETE);
-                 downloadSwfObject();
-             }
-         }
+        protected function handlSWFObjectDownload(event:Event):void
+        {
+            log(_viewResourceConstants.INFO_DOWNLOADED);
+            var swfObjectZipFile:File = File.userDirectory.resolvePath(_flexTemp + File.separator + SWF_OBJECT_FILE);
+            writeFileToDirectory(swfObjectZipFile, event.target.data);
+            unzip(swfObjectZipFile, handleSWFObjectUnzipComplete, handleSWFObjectZipFileUnzipError);
+        }
 
-         protected function downloadSwfObject():void
-         {
-             updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_SWFOBJECT, StepItem.ACTIVE);
+        protected function handleSWFObjectDownloadError(event:ErrorEvent = null):void
+        {
+            updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_SWFOBJECT, StepItem.ERROR);
+            log(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_SWF_OBJECT);
+            abortInstallation();
+        }
 
-             try
-             {
-                 log(StringUtil.substitute(_viewResourceConstants.INFO_DOWNLOADING_FILE_FROM, [SWF_OBJECT_FILE, SWF_OBJECT_URL]));
-                 copyOrDownload(SWF_OBJECT_URL + SWF_OBJECT_FILE, handlSWFObjectDownload, null, handleSWFObjectDownloadError);
-             }
-             catch (e:Error)
-             {
-                 updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_SWFOBJECT, StepItem.ERROR);
-                 abortInstallation();
-             }
-         }
+        protected function handleSWFObjectUnzipComplete(event:Event):void
+        {
+            try
+            {
+                var expressInstallFile:File = File.userDirectory.resolvePath(_flexHome + File.separator + "swfobject" + File.separator + "expressInstall.swf");
+                expressInstallFile.copyTo(_flexHomeDir.resolvePath("templates" + File.separator + "swfobject" + File.separator + "expressInstall.swf"));
 
-         protected function handlSWFObjectDownload(event:Event):void
-         {
-             log(_viewResourceConstants.INFO_DOWNLOADED);
-             var swfObjectZipFile:File = File.userDirectory.resolvePath(_flexTemp + File.separator + SWF_OBJECT_FILE);
-             writeFileToDirectory(swfObjectZipFile, event.target.data);
-             unzip(swfObjectZipFile, handleSWFObjectUnzipComplete, handleSWFObjectZipFileUnzipError);
-         }
+                var swfObjectJSFile:File = File.userDirectory.resolvePath(_flexHome + File.separator + "swfobject" + File.separator + "swfobject.js");
+                swfObjectJSFile.copyTo(_flexHomeDir.resolvePath("templates" + File.separator + "swfobject" + File.separator + "swfobject.js"));
 
-         protected function handleSWFObjectDownloadError(event:ErrorEvent = null):void
-         {
-             updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_SWFOBJECT, StepItem.ERROR);
-             log(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_SWF_OBJECT);
-             abortInstallation();
-         }
+                swfObjectJSFile.copyTo(_flexHomeDir.resolvePath("javascript" + File.separator + "FABridge" + File.separator + "samples" + File.separator
+                        + "fabridge" + File.separator + "swfobject" + File.separator + "swfobject.js"));
 
-         protected function handleSWFObjectUnzipComplete(event:Event):void
-         {
-             try
-             {
-                 var expressInstallFile:File = File.userDirectory.resolvePath(_flexHome + File.separator + "swfobject" + File.separator + "expressInstall.swf");
-                 expressInstallFile.copyTo(_flexHomeDir.resolvePath("templates" + File.separator + "swfobject" + File.separator + "expressInstall.swf"));
+                var swfObjectDir:File = _flexHomeDir.resolvePath("swfobject");
+                swfObjectDir.deleteDirectory(true);
 
-                 var swfObjectJSFile:File = File.userDirectory.resolvePath(_flexHome + File.separator + "swfobject" + File.separator + "swfobject.js");
-                 swfObjectJSFile.copyTo(_flexHomeDir.resolvePath("templates" + File.separator + "swfobject" + File.separator + "swfobject.js"));
+                updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_SWFOBJECT, StepItem.COMPLETE);
+                installOSMF();
 
-                 swfObjectJSFile.copyTo(_flexHomeDir.resolvePath("javascript" + File.separator + "FABridge" + File.separator + "samples" + File.separator
-                 + "fabridge" + File.separator + "swfobject" + File.separator + "swfobject.js"));
+            }
+            catch (e:Error)
+            {
+                updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_SWFOBJECT, StepItem.ERROR);
+                log(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_SWF_OBJECT);
+                abortInstallation();
+            }
 
-                 var swfObjectDir:File = _flexHomeDir.resolvePath("swfobject");
-                 swfObjectDir.deleteDirectory(true);
+        }
 
-                 updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_SWFOBJECT, StepItem.COMPLETE);
-                 installOSMF();
+        protected function handleSWFObjectZipFileUnzipError(event:Event):void
+        {
+            updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_SWFOBJECT, StepItem.ERROR);
+            log(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_SWF_OBJECT);
+            abortInstallation();
+        }
 
-             }
-             catch (e:Error)
-             {
-                 updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_SWFOBJECT, StepItem.ERROR);
-                 log(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_SWF_OBJECT);
-                 abortInstallation();
-             }
+        protected function installNextOptionalComponent():void
+        {
+            for each (var obj:InstallerComponentVO in _installerComponentsDataProvider)
+            {
+                if (obj.selected && !obj.installed && !obj.aborted)
+                {
+                    switch (obj.label)
+                    {
+                        case _viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS:
+                        {
+                            installBlazeDS();
+                            return;
+                            break;
+                        }
+                        case _viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF:
+                        {
+                            installFontSwf();
+                            return;
+                            break;
+                        }
+                        default:
+                        {
+                            break;
+                        }
+                    }
+                }
+            }
+            checkAndHandleAllOptionalComponentsInstalled();
+        }
 
-         }
+        protected function installBlazeDS():void
+        {
+            updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS, StepItem.ACTIVE);
+            log(StringUtil.substitute(_viewResourceConstants.INFO_DOWNLOADING_FILE_FROM, [BLAZEDS_FILE, BLAZEDS_URL]));
+            _blazeDSJarFile = File.userDirectory.resolvePath(_flexTemp + File.separator + BLAZEDS_FILE);
+            copyOrDownload(BLAZEDS_URL + BLAZEDS_FILE, handleBlazeDSDownloadComplete, null, handleBlazeDSInstallError);
+        }
 
-         protected function handleSWFObjectZipFileUnzipError(event:Event):void
-         {
-             updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_SWFOBJECT, StepItem.ERROR);
-             log(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_SWF_OBJECT);
-             abortInstallation();
-         }
+        protected function handleBlazeDSDownloadComplete(event:Event):void
+        {
+            try
+            {
+                writeFileToDirectory(_blazeDSJarFile, event.target.data);
+                copyFileToOptionalLibDir(_blazeDSJarFile);
+                updateOptionalComponentInstallStatus(_viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS, true);
+                updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS, false);
+                updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS, StepItem.COMPLETE);
+                clearData(ApacheURLLoader(event.target));
+                installNextOptionalComponent();
+            }
+            catch (e:Error)
+            {
+                updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS, StepItem.ERROR);
+                updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS, true);
+                installNextOptionalComponent();
+            }
+        }
 
-         protected function installNextOptionalComponent():void
-         {
-             for each (var obj:InstallerComponentVO in _installerComponentsDataProvider)
-             {
-                 if (obj.selected && !obj.installed && !obj.aborted)
-                 {
-                     switch (obj.label)
-                     {
-                         case _viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS:
-                         {
-                             installBlazeDS();
-                             return;
-                             break;
-                         }
-                         case _viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF:
-                         {
-                             installFontSwf();
-                             return;
-                             break;
-                         }
-                         default:
-                         {
-                             break;
-                         }
-                     }
-                 }
-             }
-             checkAndHandleAllOptionalComponentsInstalled();
-         }
+        protected function installFontSwf():void
+        {
+            updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, StepItem.ACTIVE);
+            downloadFontSwfAFEFile();
+        }
 
-         protected function installBlazeDS():void
-         {
-             updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS, StepItem.ACTIVE);
-             log(StringUtil.substitute(_viewResourceConstants.INFO_DOWNLOADING_FILE_FROM, [BLAZEDS_FILE, BLAZEDS_URL]));
-             _blazeDSJarFile = File.userDirectory.resolvePath(_flexTemp + File.separator + BLAZEDS_FILE);
-             copyOrDownload(BLAZEDS_URL + BLAZEDS_FILE, handleBlazeDSDownloadComplete, null, handleBlazeDSInstallError);
-         }
+        protected function downloadFontSwfAFEFile():void
+        {
+            log(StringUtil.substitute(_viewResourceConstants.INFO_DOWNLOADING_FILE_FROM, [AFE_FILE, AFE_URL]));
+            _afeJarFile = File.userDirectory.resolvePath(_flexTemp + File.separator + AFE_FILE);
+            copyOrDownload(AFE_URL + AFE_FILE, handleFontSWFAFEFileDownloaded, null, handleFontSWFInstallError);
+        }
 
-         protected function handleBlazeDSDownloadComplete(event:Event):void
-         {
-             try
-             {
-                 writeFileToDirectory(_blazeDSJarFile, event.target.data);
-                 copyFileToOptionalLibDir(_blazeDSJarFile);
-                 updateOptionalComponentInstallStatus(_viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS, true);
-                 updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS, false);
-                 updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS, StepItem.COMPLETE);
-                 clearData(URLLoader(event.target));
-                 installNextOptionalComponent();
-             }
-             catch (e:Error)
-             {
-                 updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS, StepItem.ERROR);
-                 updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS, true);
-                 installNextOptionalComponent();
-             }
-         }
+        protected function handleFontSWFAFEFileDownloaded(event:Event):void
+        {
+            try
+            {
+                writeFileToDirectory(_afeJarFile, event.target.data);
+                copyFileToOptionalLibDir(_afeJarFile);
+                clearData(ApacheURLLoader(event.target));
 
-         protected function installFontSwf():void
-         {
-             updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, StepItem.ACTIVE);
-             downloadFontSwfAFEFile();
-         }
+                downloadFontSwfAGLFile();
 
-         protected function downloadFontSwfAFEFile():void
-         {
-             log(StringUtil.substitute(_viewResourceConstants.INFO_DOWNLOADING_FILE_FROM, [AFE_FILE, AFE_URL]));
-             _afeJarFile = File.userDirectory.resolvePath(_flexTemp + File.separator + AFE_FILE);
-             copyOrDownload(AFE_URL + AFE_FILE, handleFontSWFAFEFileDownloaded, null, handleFontSWFInstallError);
-         }
+            }
+            catch (e:Error)
+            {
+                updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, StepItem.ERROR);
+                updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, true);
+                installNextOptionalComponent();
+            }
+        }
 
-         protected function handleFontSWFAFEFileDownloaded(event:Event):void
-         {
-             try
-             {
-                 writeFileToDirectory(_afeJarFile, event.target.data);
-                 copyFileToOptionalLibDir(_afeJarFile);
-                 clearData(URLLoader(event.target));
+        protected function downloadFontSwfAGLFile():void
+        {
+            log(StringUtil.substitute(_viewResourceConstants.INFO_DOWNLOADING_FILE_FROM, [AGLJ40_FILE, AGLJ40_URL]));
+            _aglj40JarFile = File.userDirectory.resolvePath(_flexTemp + File.separator + AGLJ40_FILE);
+            copyOrDownload(AGLJ40_URL + AGLJ40_FILE, handleFontSWFAGLFileDownloaded, null, handleFontSWFInstallError);
+        }
 
-                 downloadFontSwfAGLFile();
+        protected function handleFontSWFAGLFileDownloaded(event:Event):void
+        {
+            try
+            {
+                writeFileToDirectory(_aglj40JarFile, event.target.data);
+                copyFileToOptionalLibDir(_aglj40JarFile);
+                clearData(ApacheURLLoader(event.target));
 
-             }
-             catch (e:Error)
-             {
-                 updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, StepItem.ERROR);
-                 updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, true);
-                 installNextOptionalComponent();
-             }
-         }
+                downloadFontSwfFlexFontKitFile();
+            }
+            catch (e:Error)
+            {
+                updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, StepItem.ERROR);
+                updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, true);
+                installNextOptionalComponent();
+            }
+        }
 
-         protected function downloadFontSwfAGLFile():void
-         {
-             log(StringUtil.substitute(_viewResourceConstants.INFO_DOWNLOADING_FILE_FROM, [AGLJ40_FILE, AGLJ40_URL]));
-             _aglj40JarFile = File.userDirectory.resolvePath(_flexTemp + File.separator + AGLJ40_FILE);
-             copyOrDownload(AGLJ40_URL + AGLJ40_FILE, handleFontSWFAGLFileDownloaded, null, handleFontSWFInstallError);
-         }
+        protected function downloadFontSwfFlexFontKitFile():void
+        {
+            log(StringUtil.substitute(_viewResourceConstants.INFO_DOWNLOADING_FILE_FROM, [FLEX_FONTKIT_FILE, FLEX_FONTKIT_URL]));
+            _flexFontKitJarFile = File.userDirectory.resolvePath(_flexTemp + File.separator + FLEX_FONTKIT_FILE);
+            copyOrDownload(FLEX_FONTKIT_URL + FLEX_FONTKIT_FILE, handleFontSWFFlexFontKitFileDownloaded, null, handleFontSWFInstallError);
+        }
 
-         protected function handleFontSWFAGLFileDownloaded(event:Event):void
-         {
-             try
-             {
-                 writeFileToDirectory(_aglj40JarFile, event.target.data);
-                 copyFileToOptionalLibDir(_aglj40JarFile);
-                 clearData(URLLoader(event.target));
+        protected function handleFontSWFFlexFontKitFileDownloaded(event:Event):void
+        {
+            try
+            {
+                writeFileToDirectory(_flexFontKitJarFile, event.target.data);
+                copyFileToOptionalLibDir(_flexFontKitJarFile);
+                clearData(ApacheURLLoader(event.target));
 
-                 downloadFontSwfFlexFontKitFile();
-             }
-             catch (e:Error)
-             {
-                 updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, StepItem.ERROR);
-                 updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, true);
-                 installNextOptionalComponent();
-             }
-         }
+                downloadFontSwfRideauKitFile();
+            }
+            catch (e:Error)
+            {
+                updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, StepItem.ERROR);
+                updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, true);
+                installNextOptionalComponent();
+            }
+        }
 
-         protected function downloadFontSwfFlexFontKitFile():void
-         {
-             log(StringUtil.substitute(_viewResourceConstants.INFO_DOWNLOADING_FILE_FROM, [FLEX_FONTKIT_FILE, FLEX_FONTKIT_URL]));
-             _flexFontKitJarFile = File.userDirectory.resolvePath(_flexTemp + File.separator + FLEX_FONTKIT_FILE);
-             copyOrDownload(FLEX_FONTKIT_URL + FLEX_FONTKIT_FILE, handleFontSWFFlexFontKitFileDownloaded, null, handleFontSWFInstallError);
-         }
+        protected function downloadFontSwfRideauKitFile():void
+        {
+            log(StringUtil.substitute(_viewResourceConstants.INFO_DOWNLOADING_FILE_FROM, [RIDEAU_FILE, RIDEAU_URL]));
+            _rideauJarFile = File.userDirectory.resolvePath(_flexTemp + File.separator + RIDEAU_FILE);
+            copyOrDownload(RIDEAU_URL + RIDEAU_FILE, handleFontSWFRideauFileDownloaded, null, handleFontSWFInstallError);
+        }
 
-         protected function handleFontSWFFlexFontKitFileDownloaded(event:Event):void
-         {
-             try
-             {
-                 writeFileToDirectory(_flexFontKitJarFile, event.target.data);
-                 copyFileToOptionalLibDir(_flexFontKitJarFile);
-                 clearData(URLLoader(event.target));
+        protected function handleFontSWFRideauFileDownloaded(event:Event):void
+        {
+            try
+            {
+                writeFileToDirectory(_rideauJarFile, event.target.data);
+                copyFileToOptionalLibDir(_rideauJarFile);
+                clearData(ApacheURLLoader(event.target));
 
-                 downloadFontSwfRideauKitFile();
-             }
-             catch (e:Error)
-             {
-                 updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, StepItem.ERROR);
-                 updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, true);
-                 installNextOptionalComponent();
-             }
-         }
+                updateOptionalComponentInstallStatus(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, true);
+                updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, false);
+                updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, StepItem.COMPLETE);
+                installNextOptionalComponent();
+            }
+            catch (e:Error)
+            {
+                updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, StepItem.ERROR);
+                updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, true);
+                installNextOptionalComponent();
+            }
+        }
 
-         protected function downloadFontSwfRideauKitFile():void
-         {
-             log(StringUtil.substitute(_viewResourceConstants.INFO_DOWNLOADING_FILE_FROM, [RIDEAU_FILE, RIDEAU_URL]));
-             _rideauJarFile = File.userDirectory.resolvePath(_flexTemp + File.separator + RIDEAU_FILE);
-             copyOrDownload(RIDEAU_URL + RIDEAU_FILE, handleFontSWFRideauFileDownloaded, null, handleFontSWFInstallError);
-         }
+        protected function installOSMF():void
+        {
+            updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, StepItem.ACTIVE);
+            downloadOSMFFile();
+        }
 
-         protected function handleFontSWFRideauFileDownloaded(event:Event):void
-         {
-             try
-             {
-                 writeFileToDirectory(_rideauJarFile, event.target.data);
-                 copyFileToOptionalLibDir(_rideauJarFile);
-                 clearData(URLLoader(event.target));
+        protected function downloadOSMFFile():void
+        {
+            _osmfSWFFile = File.userDirectory.resolvePath(_flexTemp + File.separator + OSMF_SWF_FILE.toLowerCase());
 
-                 updateOptionalComponentInstallStatus(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, true);
-                 updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, false);
-                 updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, StepItem.COMPLETE);
-                 installNextOptionalComponent();
-             }
-             catch (e:Error)
-             {
-                 updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, StepItem.ERROR);
-                 updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, true);
-                 installNextOptionalComponent();
-             }
-         }
+            log(StringUtil.substitute(_viewResourceConstants.INFO_DOWNLOADING_FILE_FROM, [OSMF_SWC_FILE, OSMF_SWC_URL]));
+            _osmfSWCFile = File.userDirectory.resolvePath(_flexTemp + File.separator + OSMF_SWC_FILE.toLowerCase());
+            if (_useOSMF2)
+            {
+                downloadOSMF2SWC();
+            }
+            else
+            {
+                copyOrDownload(OSMF_SWC_URL + OSMF_SWC_FILE, handleOSMFSWCFileDownloaded, null, handleOSMFSWCInstallError);
+            }
+        }
 
-         protected function installOSMF():void
-         {
-             updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, StepItem.ACTIVE);
-             downloadOSMFFile();
-         }
+        protected function downloadOSMF2SWC():void
+        {
+            var url:String;
+            var httpService:HTTPService = new HTTPService();
+            httpService.resultFormat = HTTPService.RESULT_FORMAT_TEXT;
+            url = httpService.url = Constants.SOURCEFORGE_DOWNLOAD_URL + OSMF_SWC_URL + OSMF_SWC_FILE;
+            if (usingDownloadCache)
+            {
+                var cacheURL:String;
+                if (url.indexOf("http") == 0)
+                {
+                    var c:int = url.indexOf("/");
+                    c = url.indexOf("/", c + 1);
+                    c = url.indexOf("/", c + 1);
+                    // that should find the slash after the server.
+                    cacheURL = url.substr(c + 1);
+                    if (debugMode)
+                    {
+                        log("http caching.  url = " + cacheURL);
+                    }
+                }
+                var cacheFile:File = File.applicationStorageDirectory.resolvePath(downloadCacheFolder);
+                cacheFile = cacheFile.resolvePath(escape(cacheURL));
+                if (debugMode)
+                {
+                    log("searching cache for " + cacheFile.url);
+                }
+                if (cacheFile.exists)
+                {
+                    if (debugMode)
+                    {
+                        log("found file in cache");
+                    }
+                    url = cacheFile.url;
+                    actuallyDownloadOSMF2SWC(new URLRequest(url));
+                    return;
+                }
+            }
+            httpService.addEventListener(ResultEvent.RESULT, getMirrorInfo);
+            httpService.addEventListener(FaultEvent.FAULT, handleOSMFSWCUnzipError);
+            httpService.send();
+        }
 
-         protected function downloadOSMFFile():void
-         {
-             _osmfSWFFile = File.userDirectory.resolvePath(_flexTemp + File.separator + OSMF_SWF_FILE.toLowerCase());
+        protected function getMirrorInfo(event:ResultEvent):void
+        {
+            var mirror:String = String(event.result);
+            mirror = mirror.substr(mirror.indexOf('use_mirror=') + 'use_mirror='.length, mirror.length);
+            mirror = mirror.substring(0, mirror.indexOf('">'));
 
-             log(StringUtil.substitute(_viewResourceConstants.INFO_DOWNLOADING_FILE_FROM, [OSMF_SWC_FILE, OSMF_SWC_URL]));
-             _osmfSWCFile = File.userDirectory.resolvePath(_flexTemp + File.separator + OSMF_SWC_FILE.toLowerCase());
-             if (_useOSMF2)
-             {
-                 downloadOSMF2SWC();
-             }
-             else
-             {
-                 copyOrDownload(OSMF_SWC_URL + OSMF_SWC_FILE, handleOSMFSWCFileDownloaded, null, handleOSMFSWCInstallError);
-             }
-         }
+            var mirrorURL:String = 'http://' + mirror + Constants.SOURCEFORGE_DL_URL + OSMF_SWC_URL + OSMF_SWC_FILE;
+            var refererURL:String = Constants.SOURCEFORGE_DOWNLOAD_URL + OSMF_SWC_URL + '/download?use_mirror=' + mirror;
 
-         protected function downloadOSMF2SWC():void
-         {
-             var url:String;
-             var httpService:HTTPService = new HTTPService();
-             httpService.resultFormat = HTTPService.RESULT_FORMAT_TEXT;
-             url = httpService.url = Constants.SOURCEFORGE_DOWNLOAD_URL + OSMF_SWC_URL + OSMF_SWC_FILE;
-             if (usingDownloadCache)
-             {
-                 var cacheURL:String;
-                 if (url.indexOf("http") == 0)
-                 {
-                     var c:int = url.indexOf("/");
-                     c = url.indexOf("/", c + 1);
-                     c = url.indexOf("/", c + 1);
-                     // that should find the slash after the server.
-                     cacheURL = url.substr(c + 1);
-                     if (debugMode)
-                         log("http caching.  url = " + cacheURL);
-                 }
-                 var cacheFile:File = File.applicationStorageDirectory.resolvePath(downloadCacheFolder);
-                 cacheFile = cacheFile.resolvePath(escape(cacheURL));
-                 if (debugMode)
-                     log("searching cache for " + cacheFile.url);
-                 if (cacheFile.exists)
-                 {
-                     if (debugMode)
-                         log("found file in cache");
-                     url = cacheFile.url;
-                     actuallyDownloadOSMF2SWC(new URLRequest(url));
-                     return;
-                 }
-             }
-             httpService.addEventListener(ResultEvent.RESULT, getMirrorInfo);
-             httpService.addEventListener(FaultEvent.FAULT, handleOSMFSWCUnzipError);
-             httpService.send();
-         }
+            var req:URLRequest = new URLRequest(mirrorURL);
+            req.requestHeaders = [new URLRequestHeader('Referer', refererURL)];
 
-         protected function getMirrorInfo(event:ResultEvent):void
-         {
-             var mirror:String = String(event.result);
-             mirror = mirror.substr(mirror.indexOf('use_mirror=') + 'use_mirror='.length, mirror.length);
-             mirror = mirror.substring(0, mirror.indexOf('">'));
+            actuallyDownloadOSMF2SWC(req);
+        }
 
-             var mirrorURL:String = 'http://' + mirror + Constants.SOURCEFORGE_DL_URL + OSMF_SWC_URL + OSMF_SWC_FILE;
-             var refererURL:String = Constants.SOURCEFORGE_DOWNLOAD_URL + OSMF_SWC_URL + '/download?use_mirror=' + mirror;
+        protected function actuallyDownloadOSMF2SWC(req:URLRequest):void
+        {
+            loader = new ApacheURLLoader();
+            loader.dataFormat = URLLoaderDataFormat.BINARY;
+            if (usingDownloadCache)
+            {
+                loader.addEventListener(Event.COMPLETE, cacheOSMF2SWC);
+            }
+            loader.addEventListener(Event.COMPLETE, handleOSMFSWCFileDownloaded);
+            loader.addEventListener(ErrorEvent.ERROR, handleOSMFSWCInstallError);
+            loader.addEventListener(IOErrorEvent.IO_ERROR, handleOSMFSWCInstallError);
 
-             var req:URLRequest = new URLRequest(mirrorURL);
-             req.requestHeaders = [new URLRequestHeader('Referer', refererURL)];
+            loader.load(req);
+        }
 
-             actuallyDownloadOSMF2SWC(req);
-         }
+        protected function cacheOSMF2SWC(event:Event):void
+        {
+            var url:String;
+            url = Constants.SOURCEFORGE_DOWNLOAD_URL + OSMF_SWC_URL + OSMF_SWC_FILE;
+            var cacheURL:String;
+            if (url.indexOf("http") == 0)
+            {
+                var c:int = url.indexOf("/");
+                c = url.indexOf("/", c + 1);
+                c = url.indexOf("/", c + 1);
+                // that should find the slash after the server.
+                cacheURL = url.substr(c + 1);
+                if (debugMode)
+                {
+                    log("http caching.  url = " + cacheURL);
+                }
+            }
+            if (cacheURL)
+            {
+                var cacheFile:File = File.applicationStorageDirectory.resolvePath(downloadCacheFolder);
+                cacheFile = cacheFile.resolvePath(escape(cacheURL));
+                if (debugMode)
+                {
+                    log("caching " + cacheFile.url);
+                }
+                if (!cacheFile.exists)
+                {
+                    var fs:FileStream = new FileStream();
+                    fs.open(cacheFile, FileMode.WRITE);
+                    var srcData:ByteArray = ByteArray(loader.data);
+                    srcData.position = 0;
+                    var ba:ByteArray = new ByteArray();
+                    srcData.readBytes(ba, 0, srcData.length);
+                    ba.position = 0;
+                    fs.writeBytes(ba, 0, ba.length);
+                    fs.close();
+                }
+                else
+                {
+                    if (debugMode)
+                    {
+                        log("file was already in cache");
+                    }
+                }
+            }
+        }
 
-         protected function actuallyDownloadOSMF2SWC(req:URLRequest):void
-         {
-             loader = new URLLoader();
-             loader.dataFormat = URLLoaderDataFormat.BINARY;
-             if (usingDownloadCache)
-                 loader.addEventListener(Event.COMPLETE, cacheOSMF2SWC);
-             loader.addEventListener(Event.COMPLETE, handleOSMFSWCFileDownloaded);
-             loader.addEventListener(ErrorEvent.ERROR, handleOSMFSWCInstallError);
-             loader.addEventListener(IOErrorEvent.IO_ERROR, handleOSMFSWCInstallError);
+        protected function handleOSMFSWCFileDownloaded(event:Event):void
+        {
+            try
+            {
+                writeFileToDirectory(_osmfSWCFile, event.target.data);
+                copyFileToLibDir(_osmfSWCFile);
+                unzip(_osmfSWCFile, handleOSMFSWCUnzipped, handleOSMFSWCUnzipError);
+                clearData(ApacheURLLoader(event.target));
 
-             loader.load(req);
-         }
+                updateOptionalComponentInstallStatus(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, true);
+                updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, false);
+                updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, StepItem.COMPLETE);
+                installNextOptionalComponent();
+            }
+            catch (e:Error)
+            {
+                updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, StepItem.ERROR);
+                updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, true);
+                abortInstallation();
+            }
+        }
 
-         protected function cacheOSMF2SWC(event:Event):void
-         {
-             var url:String;
-             url = Constants.SOURCEFORGE_DOWNLOAD_URL + OSMF_SWC_URL + OSMF_SWC_FILE;
-             var cacheURL:String;
-             if (url.indexOf("http") == 0)
-             {
-                 var c:int = url.indexOf("/");
-                 c = url.indexOf("/", c + 1);
-                 c = url.indexOf("/", c + 1);
-                 // that should find the slash after the server.
-                 cacheURL = url.substr(c + 1);
-                 if (debugMode)
-                     log("http caching.  url = " + cacheURL);
-             }
-             if (cacheURL)
-             {
-                 var cacheFile:File = File.applicationStorageDirectory.resolvePath(downloadCacheFolder);
-                 cacheFile = cacheFile.resolvePath(escape(cacheURL));
-                 if (debugMode)
-                     log("caching " + cacheFile.url);
-                 if (!cacheFile.exists)
-                 {
-                     var fs:FileStream = new FileStream();
-                     fs.open(cacheFile, FileMode.WRITE);
-                     var srcData:ByteArray = ByteArray(loader.data);
-                     srcData.position = 0;
-                     var ba:ByteArray = new ByteArray();
-                     srcData.readBytes(ba, 0, srcData.length);
-                     ba.position = 0;
-                     fs.writeBytes(ba, 0, ba.length);
-                     fs.close();
-                 }
-                 else
-                 {
-                     if (debugMode)
-                         log("file was already in cache");
-                 }
-             }
-         }
+        /**
+         * Unzip osmf.swc, extract library.swf from it and copy it into frameworks/rsls/osmf_<flexversion>.<buildnumber>
+         * Delete other files extracted from osmf.swc
+         */
+        protected function handleOSMFSWCUnzipped(event:Event):void
+        {
+            try
+            {
+                var osmfFileName:String = "osmf_" + getFlexVersionBuildString() + ".swf";
+                var copyToFile:File = _flexHomeDir.resolvePath("frameworks" + File.separator + "rsls" + File.separator + osmfFileName);
+                var osmfLibrarySwfFile:File = _flexHomeDir.resolvePath("library.swf");
+                osmfLibrarySwfFile.moveTo(copyToFile);
+                var catalogXMLFile:File = _flexHomeDir.resolvePath("catalog.xml");
+                if (catalogXMLFile.exists)
+                {
+                    catalogXMLFile.deleteFile();
+                }
+                var manifestXMLFile:File = _flexHomeDir.resolvePath("manifest.xml");
+                if (manifestXMLFile.exists)
+                {
+                    manifestXMLFile.deleteFile();
+                }
+            }
+            catch (e:Error)
+            {
+                updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, StepItem.ERROR);
+                updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, true);
+                abortInstallation();
+            }
+        }
 
-         protected function handleOSMFSWCFileDownloaded(event:Event):void
-         {
-             try
-             {
-                 writeFileToDirectory(_osmfSWCFile, event.target.data);
-                 copyFileToLibDir(_osmfSWCFile);
-                 unzip(_osmfSWCFile, handleOSMFSWCUnzipped, handleOSMFSWCUnzipError);
-                 clearData(URLLoader(event.target));
+        protected function handleOSMFSWCUnzipError(event:Event):void
+        {
+            updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, StepItem.ERROR);
+            updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, true);
+            abortInstallation();
+        }
 
-                 updateOptionalComponentInstallStatus(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, true);
-                 updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, false);
-                 updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, StepItem.COMPLETE);
-                 installNextOptionalComponent();
-             }
-             catch (e:Error)
-             {
-                 updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, StepItem.ERROR);
-                 updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, true);
-                 abortInstallation();
-             }
-         }
+        protected function copyFileToOptionalLibDir(file:File):void
+        {
+            //Copy to "${FLEX_HOME}/lib/external/optional"
+            var copyToFile:File = _flexHomeDir.resolvePath("lib" + File.separator + "external" + File.separator + "optional" + File.separator + file.name);
+            file.copyTo(copyToFile, true);
+        }
 
-         /**
-          * Unzip osmf.swc, extract library.swf from it and copy it into frameworks/rsls/osmf_<flexversion>.<buildnumber>
-          * Delete other files extracted from osmf.swc
-          */
-         protected function handleOSMFSWCUnzipped(event:Event):void
-         {
-             try
-             {
-                 var osmfFileName:String = "osmf_" + getFlexVersionBuildString() + ".swf";
-                 var copyToFile:File = _flexHomeDir.resolvePath("frameworks" + File.separator + "rsls" + File.separator + osmfFileName);
-                 var osmfLibrarySwfFile:File = _flexHomeDir.resolvePath("library.swf");
-                 osmfLibrarySwfFile.moveTo(copyToFile);
-                 var catalogXMLFile:File = _flexHomeDir.resolvePath("catalog.xml");
-                 if (catalogXMLFile.exists)
-                 {
-                     catalogXMLFile.deleteFile();
-                 }
-                 var manifestXMLFile:File = _flexHomeDir.resolvePath("manifest.xml");
-                 if (manifestXMLFile.exists)
-                 {
-                     manifestXMLFile.deleteFile();
-                 }
-             }
-             catch (e:Error)
-             {
-                 updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, StepItem.ERROR);
-                 updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, true);
-                 abortInstallation();
-             }
-         }
+        protected function copyFileToLibDir(file:File):void
+        {
+            //Copy to "${FLEX_HOME}/frameworks/libs/"
+            var copyToFile:File = _flexHomeDir.resolvePath("frameworks" + File.separator + "libs" + File.separator + file.name);
+            file.copyTo(copyToFile, true);
+        }
 
-         protected function handleOSMFSWCUnzipError(event:Event):void
-         {
-             updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, StepItem.ERROR);
-             updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, true);
-             abortInstallation();
-         }
+        protected function handleBlazeDSInstallError(event:* = null):void
+        {
+            updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS, StepItem.ERROR);
+            updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS, true);
+            log(StringUtil.substitute(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_FILE, ["BlazeDS"]));
+            installNextOptionalComponent();
+        }
+
+        protected function handleFontSWFInstallError(event:* = null):void
+        {
+            updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, StepItem.ERROR);
+            updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, true);
+            log(StringUtil.substitute(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_FILE, ["FontSwf Utility"]));
+            installNextOptionalComponent();
+        }
 
-         protected function copyFileToOptionalLibDir(file:File):void
-         {
-             //Copy to "${FLEX_HOME}/lib/external/optional"
-             var copyToFile:File = _flexHomeDir.resolvePath("lib" + File.separator + "external" + File.separator + "optional" + File.separator + file.name);
-             file.copyTo(copyToFile, true);
-         }
+        protected function handleOSMFSWFInstallError(event:* = null):void
+        {
+            updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, StepItem.ERROR);
+            updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, true);
+            log(StringUtil.substitute(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_FILE, ["OSMF_SWF"]));
+            installNextOptionalComponent();
+        }
 
-         protected function copyFileToLibDir(file:File):void
-         {
-             //Copy to "${FLEX_HOME}/frameworks/libs/"
-             var copyToFile:File = _flexHomeDir.resolvePath("frameworks" + File.separator + "libs" + File.separator + file.name);
-             file.copyTo(copyToFile, true);
-         }
+        protected function handleOSMFSWCInstallError(event:* = null):void
+        {
+            updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, StepItem.ERROR);
+            updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, true);
+            log(StringUtil.substitute(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_FILE, ["OSMF_SWC"]));
+            installNextOptionalComponent();
+        }
 
-         protected function handleBlazeDSInstallError(event:* = null):void
-         {
-             updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS, StepItem.ERROR);
-             updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS, true);
-             log(StringUtil.substitute(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_FILE, ["BlazeDS"]));
-             installNextOptionalComponent();
-         }
+        protected function updateOptionalComponentInstallStatus(label:String, isInstalled:Boolean):void
+        {
+            for each (var obj:InstallerComponentVO in _installerComponentsDataProvider)
+            {
+                if (obj.label == label)
+                {
+                    obj.installed = isInstalled;
+                }
+            }
+        }
 
-         protected function handleFontSWFInstallError(event:* = null):void
-         {
-             updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, StepItem.ERROR);
-             updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, true);
-             log(StringUtil.substitute(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_FILE, ["FontSwf Utility"]));
-             installNextOptionalComponent();
-         }
+        protected function updateOptionalComponentInstallStatusAborted(label:String, isAborted:Boolean):void
+        {
+            for each (var obj:InstallerComponentVO in _installerComponentsDataProvider)
+            {
+                if (obj.label == label)
+                {
+                    obj.aborted = isAborted;
+                }
+            }
+        }
 
-         protected function handleOSMFSWFInstallError(event:* = null):void
-         {
-             updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, StepItem.ERROR);
-             updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, true);
-             log(StringUtil.substitute(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_FILE, ["OSMF_SWF"]));
-             installNextOptionalComponent();
-         }
+        protected function checkAndHandleAllOptionalComponentsInstalled():void
+        {
+            var allComponentsInstalled:Boolean = true;
+            for each (var obj:InstallerComponentVO in _installerComponentsDataProvider)
+            {
+                if (!obj.required && obj.selected && !(obj.installed || obj.aborted))
+                {
+                    allComponentsInstalled = false;
+                }
+            }
+            if (allComponentsInstalled)
+            {
+                tracker.trackInstallerSuccess(APACHE_FLEX_BIN_DISTRO_VERSION_DISPLAY, APACHE_FLEX_BIN_DISTRO_VERSION, _os.os);
+                cleanup(false);
+            }
+        }
 
-         protected function handleOSMFSWCInstallError(event:* = null):void
-         {
-             updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, StepItem.ERROR);
-             updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, true);
-             log(StringUtil.substitute(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_FILE, ["OSMF_SWC"]));
-             installNextOptionalComponent();
-         }
+        protected function cleanup(isAbort:Boolean = false, abortInfo:String = ""):void
+        {
+            if (cleanedUp)
+            {
+                return;
+            }
 
-         protected function updateOptionalComponentInstallStatus(label:String, isInstalled:Boolean):void
-         {
-             for each (var obj:InstallerComponentVO in _installerComponentsDataProvider)
-             {
-                 if (obj.label == label)
-                 {
-                     obj.installed = isInstalled;
-                 }
-             }
-         }
+            cleanedUp = true;
 
-         protected function updateOptionalComponentInstallStatusAborted(label:String, isAborted:Boolean):void
-         {
-             for each (var obj:InstallerComponentVO in _installerComponentsDataProvider)
-             {
-                 if (obj.label == label)
-                 {
-                     obj.aborted = isAborted;
-                 }
-             }
-         }
+            CursorManager.removeBusyCursor();
+            if (!_viewResourceConstants)
+            {
+                selectDefaultLanguageInEmergency();
+            }
+            try
+            {
+                if (_flexTempDir)
+                {
+                    _flexTempDir.deleteDirectory(true);
+                }
+            }
+            catch (e:Error)
+            {
+                log(_viewResourceConstants.ERROR_UNABLE_TO_DELETE_TEMP_DIRECTORY);
+            }
 
-         protected function checkAndHandleAllOptionalComponentsInstalled():void
-         {
-             var allComponentsInstalled:Boolean = true;
-             for each (var obj:InstallerComponentVO in _installerComponentsDataProvider)
-             {
-                 if (!obj.required && obj.selected && !(obj.installed || obj.aborted))
-                 {
-                     allComponentsInstalled = false;
-                 }
-             }
-             if (allComponentsInstalled)
-             {
-                 tracker.trackInstallerSuccess(APACHE_FLEX_BIN_DISTRO_VERSION_DISPLAY, APACHE_FLEX_BIN_DISTRO_VERSION, _os.os);
-                 cleanup(false);
-             }
-         }
+            if (isAbort)
+            {
+                tracker.trackInstallerFailure(APACHE_FLEX_BIN_DISTRO_VERSION_DISPLAY, APACHE_FLEX_BIN_DISTRO_VERSION,
+                        _os.os + "&info=" + abortInfo);
+            }
+            else if (!wasAborted)
+            {
+                log(_viewResourceConstants.INFO_INSTALLATION_COMPLETE);
+                updateUIHandleInstallationComplete();
+            }
 
-         protected function cleanup(isAbort:Boolean = false, abortInfo:String = ""):void
-         {
-             if (cleanedUp)
-                 return;
+            saveLogToDisk();
+        }
 
-             cleanedUp = true;
+        protected function saveLogToDisk():void
+        {
+            if (!_flexHomeDir)
+            {
+                return;
+            }
 
-             CursorManager.removeBusyCursor();
-             if (!_viewResourceConstants)
-             {
-                 selectDefaultLanguageInEmergency();
-             }
-             try
-             {
-                 if (_flexTempDir)
-                 {
-                     _flexTempDir.deleteDirectory(true);
-                 }
-             }
-             catch (e:Error)
-             {
-                 log(_viewResourceConstants.ERROR_UNABLE_TO_DELETE_TEMP_DIRECTORY);
-             }
+            var file:File = _flexHomeDir.resolvePath("installer.log");
+            var fs:FileStream = new FileStream();
 
-             if (isAbort)
-             {
-                 tracker.trackInstallerFailure(APACHE_FLEX_BIN_DISTRO_VERSION_DISPLAY, APACHE_FLEX_BIN_DISTRO_VERSION,
-                         _os.os + "&info=" + abortInfo);
-             }
-             else if (!wasAborted)
-             {
-                 log(_viewResourceConstants.INFO_INSTALLATION_COMPLETE);
-                 updateUIHandleInstallationComplete();
-             }
+            try
+            {
+                fs.open(file, FileMode.WRITE);
+                for each (var message:String in _messages)
+                {
+                    fs.writeUTFBytes(message);
+                    fs.writeUTFBytes("\n");
+                }
+                fs.close();
+            }
+            catch (e:Error)
+            {
+                // TODO log error?
+            }
+        }
 
-             saveLogToDisk();
-         }
+        protected function updateUIHandleInstallationComplete():void
+        {
+            browseBtn.enabled = true;
+            openApacheFlexFolderBtn.visible = true;
+            openApacheFlexFolderBtn.includeInLayout = true;
+            progressBar.visible = false;
+            progressBar.includeInLayout = false;
+            thirdStepGroup.title = _viewResourceConstants.INFO_INSTALLATION_COMPLETE;
+        }
 
-         protected function saveLogToDisk():void
-         {
-             if (!_flexHomeDir)
-             {
-                 return;
-             }
+        protected function abortInstallation(reason:String = ""):void
+        {
+            if (currentState != "installState")
+            {
+                showConsole(null);
+            }
 
-             var file:File = _flexHomeDir.resolvePath("installer.log");
-             var fs:FileStream = new FileStream();
+            directoryBtn.enabled = false;
+            browseBtn.enabled = false;
+            installBtn.enabled = false;
+            wasAborted = true;
+            if (_viewResourceConstants)
+            {
+                log(_viewResourceConstants.INFO_ABORT_INSTALLATION);
+            }
+            cleanup(true, reason);
+            if (_viewResourceConstants)
+            {
+                firstStepGroup.title = secondStepGroup.title = thirdStepGroup.title = _viewResourceConstants.INFO_ABORT_INSTALLATION;
+            }
+        }
 
-             try
-             {
-                 fs.open(file, FileMode.WRITE);
-                 for each (var message:String in _messages)
-                 {
-                     fs.writeUTFBytes(message);
-                     fs.writeUTFBytes("\n");
-                 }
-                 fs.close();
-             }
-             catch (e:Error)
-             {
-                 // TODO log error?
-             }
-         }
+        protected function _langSelect_changeHandler(event:IndexChangeEvent):void
+        {
+            var defaultLanguage:String = ViewResourceConstants.DEFAULT_LANGUAGE;
 
-         protected function updateUIHandleInstallationComplete():void
-         {
-             browseBtn.enabled = true;
-             openApacheFlexFolderBtn.visible = true;
-             openApacheFlexFolderBtn.includeInLayout = true;
-             progressBar.visible = false;
-             progressBar.includeInLayout = false;
-             thirdStepGroup.title = _viewResourceConstants.INFO_INSTALLATION_COMPLETE;
-         }
+            var so:SharedObject = SharedObject.getLocal("InstallApacheFlex");
+            so.data.userDefaultLanguage = _langSelect.selectedItem["data"];
+            so.flush();
 
-         protected function abortInstallation(reason:String = ""):void
-         {
-             if (currentState != "installState")
-                 showConsole(null);
+            if (_langSelect.selectedItem["data"] == defaultLanguage)
+            {
+                resourceManager.localeChain = [defaultLanguage];
+                resourceManager.update();
+                setButtonWidths();
+            }
+            else
+            {
+                loadLanguage(_langSelect.selectedItem["data"], _langSelect_changeCompleteHandler);
+            }
+        }
 
-             directoryBtn.enabled = false;
-             browseBtn.enabled = false;
-             installBtn.enabled = false;
-             wasAborted = true;
-             if (_viewResourceConstants)
-                 log(_viewResourceConstants.INFO_ABORT_INSTALLATION);
-             cleanup(true, reason);
-             if (_viewResourceConstants)
-                 firstStepGroup.title = secondStepGroup.title = thirdStepGroup.title = _viewResourceConstants.INFO_ABORT_INSTALLATION;
-         }
+        private function _langSelect_changeCompleteHandler():void
+        {
+            var defaultLanguage:String = ViewResourceConstants.DEFAULT_LANGUAGE;
+            resourceManager.localeChain = [languageID, defaultLanguage];
+            resourceManager.update();
+            log("Using Locale: " + languageID);
+            setButtonWidths();
+        }
 
-         protected function _langSelect_changeHandler(event:IndexChangeEvent):void
-         {
-             var defaultLanguage:String = ViewResourceConstants.DEFAULT_LANGUAGE;
+        override protected function resourcesChanged():void
+        {
+            super.resourcesChanged();
 
-             var so:SharedObject = SharedObject.getLocal("InstallApacheFlex");
-             so.data.userDefaultLanguage = _langSelect.selectedItem["data"];
-             so.flush();
+            if (_viewResourceConstants)
+            {
+                rememberInstallerComponents();
+                updateWindowTitle();
+                initiateInstallStepsActivity();
+                initializeInstallerComponentsDataProvider();
+                recallInstallerComponents();
 
-             if (_langSelect.selectedItem["data"] == defaultLanguage)
-             {
-                 resourceManager.localeChain = [defaultLanguage];
-                 resourceManager.update();
-                 setButtonWidths();
-             }
-             else
-             {
-                 loadLanguage(_langSelect.selectedItem["data"], _langSelect_changeCompleteHandler);
-             }
-         }
+                // This makes sure to update the Title of the license being displayed if the user changes languages
+                _currentLicenseLabel = _installerComponentsDataProvider.getItemAt(lastLicenseItemSelected).licenseName;
 
-         private function _langSelect_changeCompleteHandler():void
-         {
-             var defaultLanguage:String = ViewResourceConstants.DEFAULT_LANGUAGE;
-             resourceManager.localeChain = [languageID, defaultLanguage];
-             resourceManager.update();
-             log("Using Locale: " + languageID);
-             setButtonWidths();
-         }
+            }
+        }
 
-         override protected function resourcesChanged():void
-         {
-             super.resourcesChanged();
+        private var _selectedInstallerComponents:Vector.<InstallerComponentVO>;
 
-             if (_viewResourceConstants)
-             {
-                 rememberInstallerComponents();
-                 updateWindowTitle();
-                 initiateInstallStepsActivity();
-                 initializeInstallerComponentsDataProvider();
-                 recallInstallerComponents();
-             }
-         }
+        protected function rememberInstallerComponents():void
+        {
+            _selectedInstallerComponents = new Vector.<InstallerComponentVO>;
+            for each(var item:InstallerComponentVO in _installerComponentsDataProvider)
+            {
+                if (item.selected)
+                {
+                    _selectedInstallerComponents.push(item);
+                }
+            }
+        }
 
-         private var _selectedInstallerComponents:Vector.<InstallerComponentVO>;
+        protected function recallInstallerComponents():void
+        {
+            for each(var item:InstallerComponentVO in _selectedInstallerComponents)
+            {
+                getInstallerComponentFromLabel(item.key).selected = true;
+            }
+        }
 
-         protected function rememberInstallerComponents():void
-         {
-             _selectedInstallerComponents = new Vector.<InstallerComponentVO>;
-             for each(var item:InstallerComponentVO in _installerComponentsDataProvider)
-             {
-                 if (item.selected)
-                 {
-                     _selectedInstallerComponents.push(item);
-                 }
-             }
-         }
+        protected function placeGroup(panel:Panel):void
+        {
+            panel.x = this.width / 2 - panel.width / 2;
+        }
 
-         protected function recallInstallerComponents():void
-         {
-             for each(var item:InstallerComponentVO in _selectedInstallerComponents)
-             {
-                 getInstallerComponentFromLabel(item.key).selected = true;
+        protected function handleOptionalInstallsChange(event:IndexChangeEvent):void
+        {
+            var selectedItem:InstallerComponentVO = InstallerComponentVO(event.target.selectedItem);
+            optionalInstallsTxtArea.text = selectedItem.message;
+            /*installChkBx.label = _viewResourceConstants.INSTALL_AGREE;
+             if (selectedItem.answered) {
+             if (selectedItem.selected) {
+             installChkBx.selected = true;
+             } else {
+             installChkBx.selected = false;
              }
-         }
+             } else {
+             installChkBx.selected = false;
+             }*/
 
-         protected function placeGroup(panel:Panel):void
-         {
-             panel.x = this.width / 2 - panel.width / 2;
-         }
+            // Store the current selected item in order to have the license title update if the language is changed
+            lastLicenseItemSelected = installComponentsList.selectedIndex;
 
-         protected function handleOptionalInstallsChange(event:IndexChangeEvent):void
-         {
-             var selectedItem:InstallerComponentVO = InstallerComponentVO(event.target.selectedItem);
-             optionalInstallsTxtArea.text = selectedItem.message;
-             licenseLinkBtn.includeInLayout = true;
-             _currentLicenseLabel = selectedItem.licenseName;
-             _currentLicenseURL = selectedItem.licenseURL;
-             checkIfAllRequiredComponentsPromptsAnswered();
+            licenseLinkBtn.includeInLayout = true;
+            _currentLicenseLabel = selectedItem.licenseName;
+            _currentLicenseURL = selectedItem.licenseURL;
+            checkIfAllRequiredComponentsPromptsAnswered();
 
-         }
+        }
 
-         protected function handleLicenceBtnClick(event:Event):void
-         {
-             navigateToURL(new URLRequest(_currentLicenseURL), "_blank");
-         }
+        protected function handleLicenceBtnClick(event:Event):void
+        {
+            navigateToURL(new URLRequest(_currentLicenseURL), "_blank");
+        }
 
-         protected function handleInstallPermissionChange(event:InstallItemSelectionEvent):void
-         {
-             if (installComponentsList.selectedItem != null)
-             {
-                 installComponentsList.selectedItem.selected = (event.item.selected);
-                 installComponentsList.selectedItem.answered = true;
-             }
-             else
-             {
-                 for (var i:int = 0; i < _installerComponentsDataProvider.length; i++)
-                 {
-                     _installerComponentsDataProvider.getItemAt(i).selected = event.item.selected;
-                     _installerComponentsDataProvider.getItemAt(i).answered = true;
-                 }
-             }
-             checkIfAllRequiredComponentsPromptsAnswered();
-         }
+        protected function handleInstallPermissionChange(event:InstallItemSelectionEvent):void
+        {
+            if (installComponentsList.selectedItem != null)
+            {
+                installComponentsList.selectedItem.selected = (event.item.selected);
+                installComponentsList.selectedItem.answered = true;
+            }
+            else
+            {
+                for (var i:int = 0; i < _installerComponentsDataProvider.length; i++)
+                {
+                    _installerComponentsDataProvider.getItemAt(i).selected = event.item.selected;
+                    _installerComponentsDataProvider.getItemAt(i).answered = true;
+                }
+            }
+            checkIfAllRequiredComponentsPromptsAnswered();
+        }
 
-         protected function checkIfAllRequiredComponentsPromptsAnswered():void
-         {
-             var success:Boolean = true;
-             for each (var obj:InstallerComponentVO in _installerComponentsDataProvider)
-             {
-                 if (obj.required && !obj.selected)
-                 {
-                     success = false;
-                 }
-             }
-             installBtn.enabled = success;
-         }
+        protected function checkIfAllRequiredComponentsPromptsAnswered():void
+        {
+            var success:Boolean = true;
+            for each (var obj:InstallerComponentVO in _installerComponentsDataProvider)
+            {
+                if (obj.required && !obj.selected)
+                {
+                    success = false;
+                }
+            }
+            installBtn.enabled = success;
+        }
 
-         /************************ Utility methods *****************/
+        /************************ Utility methods *****************/
 
-         private function createFolder(path:String):File
-         {
-             var dir:File = new File(path);
+        private function createFolder(path:String):File
+        {
+            var dir:File = new File(path);
 
-             if (!dir.exists)
-                 dir.createDirectory();
+            if (!dir.exists)
+            {
+                dir.createDirectory();
+            }
 
-             return dir;
-         }
+            return dir;
+        }
 
-         private function copyOrDownload(url:String, handlerFunction:Function, dest:File = null, errorFunction:Function = null, nocache:Boolean = false):void
-         {
-             if (url.search("http") == 0)
-             {
-                 download(url, handlerFunction, errorFunction, nocache);
-             }
-             else if (url.search("file://") == 0)
-             {
-                 download(url, handlerFunction, errorFunction, nocache);
-             }
-             else
-             {
-                 var source:File = new File(url);
+        private function copyOrDownload(url:String, handlerFunction:Function, dest:File = null, errorFunction:Function = null, nocache:Boolean = false):void
+        {
+            if (url.search("http") == 0)
+            {
+                download(url, handlerFunction, errorFunction, nocache);
+            }
+            else if (url.search("file://") == 0)
+            {
+                download(url, handlerFunction, errorFunction, nocache);
+            }
+            else
+            {
+                var source:File = new File(url);
 
-                 try
-                 {
-                     source.copyTo(dest, true);
-                 }
-                 catch (error:Error)
-                 {
-                     if (errorFunction != null)
-                     {
-                         errorFunction.call(null);
-                     }
-                     log(_viewResourceConstants.ERROR_UNABLE_TO_COPY_FILE + error.errorID + " " + error.message);
-                 }
-             }
-         }
+                try
+                {
+                    source.copyTo(dest, true);
+                }
+                catch (error:Error)
+                {
+                    if (errorFunction != null)
+                    {
+                        errorFunction.call(null);
+                    }
+                    log(_viewResourceConstants.ERROR_UNABLE_TO_COPY_FILE + error.errorID + " " + error.message);
+                }
+            }
+        }
 
-         private function download(url:String, handlerFunction:Function, errorFunction:Function = null, nocache:Boolean = false):void
-         {
-             loader = new URLLoader();
-             if (debugMode)
-             {
-                 log("downloading " + url);
-                 if (usingDownloadCache)
-                     log("using download cache");
-                 if (nocache)
-                     log("not caching this download");
-             }
-             if (usingDownloadCache && !nocache)
-             {
-                 var cacheURL:String;
-                 if (_useMirror && url.indexOf(useMirrorPath(_mirrorURLUtil.mirrorURL)) != -1)
-                 {
-                     cacheURL = url.substr(useMirrorPath(_mirrorURLUtil.mirrorURL).length);
-                     if (debugMode)
-                         log("mirror caching.  url = " + cacheURL);
-                 }
-                 else
-                 {
-                     if (url.indexOf("http") == 0)
-                     {
-                         var c:int = url.indexOf("/");
-                         c = url.indexOf("/", c + 1);
-                         c = url.indexOf("/", c + 1);
-                         // that should find the slash after the server.
-                         cacheURL = url.substr(c + 1);
-                         if (debugMode)
-                             log("http caching.  url = " + cacheURL);
-                     }
-                 }
-                 if (cacheURL)
-                 {
-                     var cacheFile:File = File.applicationStorageDirectory.resolvePath(downloadCacheFolder);
-                     cacheFile = cacheFile.resolvePath(escape(cacheURL));
-                     if (debugMode)
-                         log("searching cache for " + cacheFile.url);
-                     if (cacheFile.exists)
-                     {
-                         log(_viewResourceConstants.INFO_USING_CACHED_FILE + " " + cacheFile.url);
-                         url = cacheFile.url;
-                     }
-                 }
-             }
-             var req:URLRequest = new URLRequest(url);
-             //Wait for 5 minutes before aborting download attempt.  Adobe download sites as well as some Apache mirrors are extremely slow.
-             req.idleTimeout = 300000;
+        private function download(url:String, handlerFunction:Function, errorFunction:Function = null, nocache:Boolean = false):void
+        {
+            loader = new ApacheURLLoader();
+            if (debugMode)
+            {
+                log("downloading " + url);
+                if (usingDownloadCache)
+                {
+                    log("using download cache");
+                }
+                if (nocache)
+                {
+                    log("not caching this download");
+                }
+            }
+            if (usingDownloadCache && !nocache)
+            {
+                var cacheURL:String;
+                if (_useMirror && url.indexOf(useMirrorPath(_mirrorURLUtil.mirrorURL)) != -1)
+                {
+                    cacheURL = url.substr(useMirrorPath(_mirrorURLUtil.mirrorURL).length);
+                    if (debugMode)
+                    {
+                        log("mirror caching.  url = " + cacheURL);
+                    }
+                }
+                else
+                {
+                    if (url.indexOf("http") == 0)
+                    {
+                        var c:int = url.indexOf("/");
+                        c = url.indexOf("/", c + 1);
+                        c = url.indexOf("/", c + 1);
+                        // that should find the slash after the server.
+                        cacheURL = url.substr(c + 1);
+                        if (debugMode)
+                        {
+                            log("http caching.  url = " + cacheURL);
+                        }
+                    }
+                }
+                if (cacheURL)
+                {
+                    var cacheFile:File = File.applicationStorageDirectory.resolvePath(downloadCacheFolder);
+                    cacheFile = cacheFile.resolvePath(escape(cacheURL));
+                    if (debugMode)
+                    {
+                        log("searching cache for " + cacheFile.url);
+                    }
+                    if (cacheFile.exists)
+                    {
+                        log(_viewResourceConstants.INFO_USING_CACHED_FILE + " " + cacheFile.url);
+                        url = cacheFile.url;
+                    }
+                }
+            }
+            var req:URLRequest = new URLRequest(url);
+            //Wait for 5 minutes before aborting download attempt.  Adobe download sites as well as some Apache mirrors are extremely slow.
+            req.idleTimeout = 300000;
 
-             loader.dataFormat = URLLoaderDataFormat.BINARY;
-             if (usingDownloadCache)
-                 loader.addEventListener(Event.COMPLETE, function (event:Event):void
-                 {
-                     if (debugMode)
-                         log("download complete preparing to cache");
-                     var cacheURL:String;
-                     if (_useMirror && url.indexOf(useMirrorPath(_mirrorURLUtil.mirrorURL)) != -1)
-                     {
-                         cacheURL = url.substr(useMirrorPath(_mirrorURLUtil.mirrorURL).length);
-                         if (debugMode)
-                             log("mirror caching.  url = " + cacheURL);
-                     }
-                     else
-                     {
-                         if (url.indexOf("http") == 0)
-                         {
-                             var c:int = url.indexOf("/");
-                             c = url.indexOf("/", c + 1);
-                             c = url.indexOf("/", c + 1);
-                             // that should find the slash after the server.
-                             cacheURL = url.substr(c + 1);
-                             if (debugMode)
-                                 log("http caching.  url = " + cacheURL);
-                         }
-                     }
-                     if (cacheURL && !nocache)
-                     {
-                         var cacheFile:File = File.applicationStorageDirectory.resolvePath(downloadCacheFolder);
-                         cacheFile = cacheFile.resolvePath(escape(cacheURL));
-                         if (debugMode)
-                             log("caching " + cacheFile.url);
-                         if (!cacheFile.exists)
-                         {
-                             var fs:FileStream = new FileStream();
-                             fs.open(cacheFile, FileMode.WRITE);
-                             var srcData:ByteArray = ByteArray(loader.data);
-                             srcData.position = 0;
-                             var ba:ByteArray = new ByteArray();
-                             srcData.readBytes(ba, 0, srcData.length);
-                             ba.position = 0;
-                             fs.writeBytes(ba, 0, ba.length);
-                             fs.close();
-                         }
-                         else
-                         {
-                             if (debugMode)
-                                 log("file was already in cache");
-                         }
-                     }
+            loader.dataFormat = URLLoaderDataFormat.BINARY;
+            if (usingDownloadCache)
+            {
+                loader.addEventListener(Event.COMPLETE, function (event:Event):void
+                {
+                    if (debugMode)
+                    {
+                        log("download complete preparing to cache");
+                    }
+                    var cacheURL:String;
+                    if (_useMirror && url.indexOf(useMirrorPath(_mirrorURLUtil.mirrorURL)) != -1)
+                    {
+                        cacheURL = url.substr(useMirrorPath(_mirrorURLUtil.mirrorURL).length);
+                        if (debugMode)
+                        {
+                            log("mirror caching.  url = " + cacheURL);
+                        }
+                    }
+                    else
+                    {
+                        if (url.indexOf("http") == 0)
+                        {
+                            var c:int = url.indexOf("/");
+                            c = url.indexOf("/", c + 1);
+                            c = url.indexOf("/", c + 1);
+                            // that should find the slash after the server.
+                            cacheURL = url.substr(c + 1);
+                            if (debugMode)
+                            {
+                                log("http caching.  url = " + cacheURL);
+                            }
+                        }
+                    }
+                    if (cacheURL && !nocache)
+                    {
+                        var cacheFile:File = File.applicationStorageDirectory.resolvePath(downloadCacheFolder);
+                        cacheFile = cacheFile.resolvePath(escape(cacheURL));
+                        if (debugMode)
+                        {
+                            log("caching " + cacheFile.url);
+                        }
+                        if (!cacheFile.exists)
+                        {
+                            var fs:FileStream = new FileStream();
+                            fs.open(cacheFile, FileMode.WRITE);
+                            var srcData:ByteArray = ByteArray(loader.data);
+                            srcData.position = 0;
+                            var ba:ByteArray = new ByteArray();
+                            srcData.readBytes(ba, 0, srcData.length);
+                            ba.position = 0;
+                            fs.writeBytes(ba, 0, ba.length);
+                            fs.close();
+                        }
+                        else
+                        {
+                            if (debugMode)
+                            {
+                                log("file was already in cache");
+                            }
+                        }
+                    }
 
-                 });
-             loader.addEventListener(Event.COMPLETE, handlerFunction, false, 0, true);
-             loader.addEventListener(Event.COMPLETE, handleDownloadComplete, false, 0, true);
+                });
+            }
+            loader.addEventListener(Event.COMPLETE, handlerFunction, false, 0, true);
+            loader.addEventListener(Event.COMPLETE, handleDownloadComplete, false, 0, true);
 
-             progressBar.percent = 0;
+            progressBar.percent = 0;
 
-             if (errorFunction != null)
-             {
-                 loader.addEventListener(ErrorEvent.ERROR, errorFunction, false, 0, true);
-                 loader.addEventListener(IOErrorEvent.IO_ERROR, errorFunction, false, 0, true);
-             }
-             loader.addEventListener(ProgressEvent.PROGRESS, handleDownloadProgress, false, 0, true);
+            if (errorFunction != null)
+            {
+                loader.addEventListener(ErrorEvent.ERROR, errorFunction, false, 0, true);
+                loader.addEventListener(IOErrorEvent.IO_ERROR, errorFunction, false, 0, true);
+            }
+            loader.addEventListener(ProgressEvent.PROGRESS, handleDownloadProgress, false, 0, true);
 
-             loader.load(req);
-         }
+            loader.load(req);
+        }
 
-         private function handleDownloadProgress(event:ProgressEvent):void
-         {
-             var bytesTotal:int = event.bytesTotal;
-             var bytesLoaded:int = event.bytesLoaded;
-             if (event.bytesTotal > 0)
-             {
-                 var percentLoaded:int = Math.round(bytesLoaded * 100 / bytesTotal);
-                 if (logProgressEvents)
-                     log("download progress " + event.bytesLoaded + "  " + event.bytesTotal, -1, false);
+        private function handleDownloadProgress(event:ProgressEvent):void
+        {
+            var bytesTotal:int = event.bytesTotal;
+            var bytesLoaded:int = event.bytesLoaded;
+            if (event.bytesTotal > 0)
+            {
+                var percentLoaded:int = Math.round(bytesLoaded * 100 / bytesTotal);
+                if (logProgressEvents)
+                {
+                    log("download progress " + event.bytesLoaded + "  " + event.bytesTotal, -1, false);
+                }
 
-                 progressBar.percent = percentLoaded;
-             }
-         }
+                progressBar.percent = percentLoaded;
+            }
+        }
 
-         private function handleDownloadComplete(event:Event):void
-         {
-             _previousDisplayedPercent = 0;
-             clearData(URLLoader(event.target));
-         }
+        private function handleDownloadComplete(event:Event):void
+        {
+            _previousDisplayedPercent = 0;
+            clearData(ApacheURLLoader(event.target));
+        }
 
-         private function clearData(v:URLLoader):void
-         {
-             ByteArray(v.data).clear();
-             System.gc();
-         }
+        private function clearData(v:ApacheURLLoader):void
+        {
+            ByteArray(v.data).clear();
+            System.gc();
+        }
 
-         private function unzip(fileToUnzip:File, unzipCompleteFunction:Function, unzipErrorFunction:Function = null):void
-         {
-             var zipFileBytes:ByteArray = new ByteArray();
-             var fs:FileStream = new FileStream();
-             var fzip:Zip = new Zip();
+        private function unzip(fileToUnzip:File, unzipCompleteFunction:Function, unzipErrorFunction:Function = null):void
+        {
+            var zipFileBytes:ByteArray = new ByteArray();
+            var fs:FileStream = new FileStream();
+            var fzip:Zip = new Zip();
 
-             fs.open(fileToUnzip, FileMode.READ);
-             fs.readBytes(zipFileBytes);
-             fs.close();
+            fs.open(fileToUnzip, FileMode.READ);
+            fs.readBytes(zipFileBytes);
+            fs.close();
 
-             fzip.addEventListener(ZipEvent.FILE_LOADED, onFileLoaded, false, 0, true);
-             fzip.addEventListener(Event.COMPLETE, unzipCompleteFunction, false, 0, true);
-             fzip.addEventListener(Event.COMPLETE, onUnzipComplete, false, 0, true);
-             if (unzipErrorFunction != null)
-             {
-                 fzip.addEventListener(ErrorEvent.ERROR, unzipErrorFunction, false, 0, true);
-                 _fileUnzipErrorFunction = unzipErrorFunction
-             }
-             fzip.loadBytes(zipFileBytes);
-         }
+            fzip.addEventListener(ZipEvent.FILE_LOADED, onFileLoaded, false, 0, true);
+            fzip.addEventListener(Event.COMPLETE, unzipCompleteFunction, false, 0, true);
+            fzip.addEventListener(Event.COMPLETE, onUnzipComplete, false, 0, true);
+            if (unzipErrorFunction != null)
+            {
+                fzip.addEventListener(ErrorEvent.ERROR, unzipErrorFunction, false, 0, true);
+                _fileUnzipErrorFunction = unzipErrorFunction
+            }
+            fzip.loadBytes(zipFileBytes);
+        }
 
-         private function onFileLoaded(e:ZipEvent):void
-         {
-             try
-             {
-                 var fzf:ZipFile = e.file;
-                 var f:File;
-                 if (overlaying)
-                     f = _flexTempDir.resolvePath(fzf.filename);
-                 else
-                     f = _flexHomeDir.resolvePath(fzf.filename);
-                 var fs:FileStream = new FileStream();
+        private function onFileLoaded(e:ZipEvent):void
+        {
+            try
+            {
+                var fzf:ZipFile = e.file;
+                var f:File;
+                if (overlaying)
+                {
+                    f = _flexTempDir.resolvePath(fzf.filename);
+                }
+                else
+                {
+                    f = _flexHomeDir.resolvePath(fzf.filename);
+                }
+                var fs:FileStream = new FileStream();
 
-                 if (isDirectory(fzf))
-                 {
-                     // Is a directory, not a file. Dont try to write anything into it.
-                     return;
-                 }
+                if (isDirectory(fzf))
+                {
+                    // Is a directory, not a file. Dont try to write anything into it.
+                    return;
+                }
 
-                 fs.open(f, FileMode.WRITE);
-                 fs.writeBytes(fzf.content);
-                 fs.close();
+                fs.open(f, FileMode.WRITE);
+                fs.writeBytes(fzf.content);
+                fs.close();
 
-             }
-             catch (error:Error)
-             {
-                 _fileUnzipErrorFunction.call();
-             }
-         }
+            }
+            catch (error:Error)
+            {
+                _fileUnzipErrorFunction.call();
+            }
+        }
 
-         private function isDirectory(f:ZipFile):Boolean
-         {
-             if (f.filename.substr(f.filename.length - 1) == "/" || f.filename.substr(f.filename.length - 1) == "\\")
-             {
-                 return true;
-             }
-             return false;
-         }
+        private function isDirectory(f:ZipFile):Boolean
+        {
+            if (f.filename.substr(f.filename.length - 1) == "/" || f.filename.substr(f.filename.length - 1) == "\\")
+            {
+                return true;
+            }
+            return false;
+        }
 
-         private function onUnzipComplete(event:Event):void
-         {
-             var fzip:Zip = event.target as Zip;
-             fzip.close();
-             fzip.removeEventListener(ZipEvent.FILE_LOADED, onFileLoaded);
-             fzip.removeEventListener(Event.COMPLETE, onUnzipComplete);
-         }
+        private function onUnzipComplete(event:Event):void
+        {
+            var fzip:Zip = event.target as Zip;
+            fzip.close();
+            fzip.removeEventListener(ZipEvent.FILE_LOADED, onFileLoaded);
+            fzip.removeEventListener(Event.COMPLETE, onUnzipComplete);
+        }
 
-         private function untar(source:File, destination:File, unTarCompleteFunction:Function, unTarErrorFunction:Function):void
-         {
-             var tar:File;
-             var startupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo();
-             var arguments:Vector.<String> = new Vector.<String>();
+        private function untar(source:File, destination:File, unTarCompleteFunction:Function, unTarErrorFunction:Function):void
+        {
+            var tar:File;
+            var startupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo();
+            var arguments:Vector.<String> = new Vector.<String>();
 
-             if (_os.isLinux())
-             {
-                 tar = new File("/bin/tar");
-             }
-             else
-             {
-                 tar = new File("/usr/bin/tar");
-             }
+            if (_os.isLinux())
+            {
+                tar = new File("/bin/tar");
+            }
+            else
+            {
+                tar = new File("/usr/bin/tar");
+            }
 
-             arguments.push("xf");
-             arguments.push(source.nativePath);
-             arguments.push("-C");
-             arguments.push(destination.nativePath);
+            arguments.push("xf");
+            arguments.push(source.nativePath);
+            arguments.push("-C");
+            arguments.push(destination.nativePath);
 
-             startupInfo.executable = tar;
-             startupInfo.arguments = arguments;
+            startupInfo.executable = tar;
+            startupInfo.arguments = arguments;
 
-             _process = new NativeProcess();
-             _process.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, unTarFileProgress, false, 0, true);
-             _process.addEventListener(ProgressEvent.STANDARD_ERROR_DATA, unTarErrorFunction, false, 0, true);
-             _process.addEventListener(ProgressEvent.STANDARD_ERROR_DATA, unTarError, false, 0, true);
-             _process.addEventListener(NativeProcessExitEvent.EXIT, unTarCompleteFunction, false, 0, true);
-             _process.addEventListener(NativeProcessExitEvent.EXIT, unTarComplete, false, 0, true);
-             _process.start(startupInfo);
-         }
+            _process = new NativeProcess();
+            _process.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, unTarFileProgress, false, 0, true);
+            _process.addEventListener(ProgressEvent.STANDARD_ERROR_DATA, unTarErrorFunction, false, 0, true);
+            _process.addEventListener(ProgressEvent.STANDARD_ERROR_DATA, unTarError, false, 0, true);
+            _process.addEventListener(NativeProcessExitEvent.EXIT, unTarCompleteFunction, false, 0, true);
+            _process.addEventListener(NativeProcessExitEvent.EXIT, unTarComplete, false, 0, true);
+            _process.start(startupInfo);
+        }
 
-         private function unTarError(event:Event):void
-         {
-             var output:String = _process.standardError.readUTFBytes(_process.standardError.bytesAvailable);
+        private function unTarError(event:Event):void
+        {
+            var output:String = _process.standardError.readUTFBytes(_process.standardError.bytesAvailable);
 
-             log(_viewResourceConstants.ERROR_NATIVE_PROCESS_ERROR);
-             log(output);
-         }
+            log(_viewResourceConstants.ERROR_NATIVE_PROCESS_ERROR);
+            log(output);
+        }
 
-         private function unTarFileProgress(event:Event):void
-         {
-             var output:String = _process.standardOutput.readUTFBytes(_process.standardOutput.bytesAvailable);
+        private function unTarFileProgress(event:Event):void
+        {
+            var output:String = _process.standardOutput.readUTFBytes(_process.standardOutput.bytesAvailable);
 
-             log(output);
-         }
+            log(output);
+        }
 
-         private function unTarComplete(event:NativeProcessExitEvent):void
-         {
-             _process.closeInput();
-             _process.exit(true);
-         }
+        private function unTarComplete(event:NativeProcessExitEvent):void
+        {
+            _process.closeInput();
+            _process.exit(true);
+        }
 
-         private function writeFileToDirectory(file:File, data:ByteArray):void
-         {
-             var fs:FileStream = new FileStream();
-             fs.open(file, FileMode.WRITE);
-             fs.writeBytes(data);
-             fs.close();
-         }
+        private function writeFileToDirectory(file:File, data:ByteArray):void
+        {
+            var fs:FileStream = new FileStream();
+            fs.open(file, FileMode.WRITE);
+            fs.writeBytes(data);
+            fs.close();
+        }
 
-         private function isValidConfigFile(file:File):Boolean
-         {
-             var name:String = file.name;
+        private function isValidConfigFile(file:File):Boolean
+        {
+            var name:String = file.name;
 
-             if (name.search("-config.xml") == -1)
-             {
-                 return false;
-             }
-             else
-             {
-                 return true;
-             }
-         }
+            if (name.search("-config.xml") == -1)
+            {
+                return false;
+            }
+            else
+            {
+                return true;
+            }
+        }
 
-         private function isAirConfigFile(file:File):Boolean
-         {
-             var name:String = file.name;
+        private function isAirConfigFile(file:File):Boolean
+        {
+            var name:String = file.name;
 
-             if (name.search("air") == 0)
-             {
-                 return true;
-             }
-             else
-             {
-                 return false;
-             }
-         }
+            if (name.search("air") == 0)
+            {
+                return true;
+            }
+            else
+            {
+                return false;
+            }
+        }
 
-         private function log(text:String, position:int = -1, isPublic:Boolean = true, skipLog:Boolean = false):void
-         {
-             if (text == null)
-                 text = "";
-             if (position == -1)
-             {
-                 if (!skipLog)
-                     _messages.addItem(text);
-                 if (isPublic)
-                     lastPublicMessage = text;
-             }
-             else
-             {
-                 _messages.addItemAt(text, position);
-             }
-             if (debugMode)
-                 trace(text);
-             if (logFile)
-             {
-                 var f:File = new File(logFile);
-                 var fs:FileStream = new FileStream();
-                 fs.open(f, FileMode.APPEND);
-                 fs.writeUTFBytes(text + "\n");
-                 fs.close();
-             }
-         }
+        private function log(text:String, position:int = -1, isPublic:Boolean = true, skipLog:Boolean = false):void
+        {
+            if (text == null)
+            {
+                text = "";
+            }
+            if (position == -1)
+            {
+                if (!skipLog)
+                {
+                    _messages.addItem(text);
+                }
+                if (isPublic)
+                {
+                    lastPublicMessage = text;
+                }
+            }
+            else
+            {
+                _messages.addItemAt(text, position);
+            }
+            if (debugMode)
+            {
+                trace(text);
+            }
+            if (logFile)
+            {
+                var f:File = new File(logFile);
+                var fs:FileStream = new FileStream();
+                fs.open(f, FileMode.APPEND);
+                fs.writeUTFBytes(text + "\n");
+                fs.close();
+            }
+        }
 
-         private var console:ConsoleWindow;
+        private var console:ConsoleWindow;
 
-         private function showConsole(event:Event):void
-         {
-             if (!console || console.closed)
-                 console = new ConsoleWindow();
-             else if (console)
-                 console.orderToFront();
+        private function showConsole(event:Event):void
+        {
+            if (!console || console.closed)
+            {
+                console = new ConsoleWindow();
+            }
+            else if (console)
+            {
+                console.orderToFront();
+            }
 
-             console.messages = _messages;
-             console.open();
-             console.nativeWindow.x = this.nativeWindow.x + this.nativeWindow.width / 2 - console.nativeWindow.width / 2;
-             console.nativeWindow.y = this.nativeWindow.y + this.nativeWindow.height / 2 - console.nativeWindow.height / 2;
-         }
+            console.messages = _messages;
+            console.open();
+            console.nativeWindow.x = this.nativeWindow.x + this.nativeWindow.width / 2 - console.nativeWindow.width / 2;
+            console.nativeWindow.y = this.nativeWindow.y + this.nativeWindow.height / 2 - console.nativeWindow.height / 2;
+        }
 
-         private function showMPLLicense(event:Event):void
-         {
-             var licenseWindow:MPLLicense = new MPLLicense();
-             licenseWindow.open();
-             licenseWindow.nativeWindow.x = this.nativeWindow.x + this.nativeWindow.width / 2 - licenseWindow.nativeWindow.width / 2;
-             licenseWindow.nativeWindow.y = this.nativeWindow.y + this.nativeWindow.height / 2 - licenseWindow.nativeWindow.height / 2;
-         }
+        private function showMPLLicense(event:Event):void
+        {
+            var licenseWindow:MPLLicense = new MPLLicense();
+            licenseWindow.open();
+            licenseWindow.nativeWindow.x = this.nativeWindow.x + this.nativeWindow.width / 2 - licenseWindow.nativeWindow.width / 2;
+            licenseWindow.nativeWindow.y = this.nativeWindow.y + this.nativeWindow.height / 2 - licenseWindow.nativeWindow.height / 2;
+        }
 
-         private function showAdobeLicense(event:Event):void
-         {
-             var licenseWindow:AdobeLicense = new AdobeLicense();
-             licenseWindow.open();
-             licenseWindow.nativeWindow.x = this.nativeWindow.x + this.nativeWindow.width / 2 - licenseWindow.nativeWindow.width / 2;
-             licenseWindow.nativeWindow.y = this.nativeWindow.y + this.nativeWindow.height / 2 - licenseWindow.nativeWindow.height / 2;
-         }
+        private function showAdobeLicense(event:Event):void
+        {
+            var licenseWindow:AdobeLicense = new AdobeLicense();
+            licenseWindow.open();
+            licenseWindow.nativeWindow.x = this.nativeWindow.x + this.nativeWindow.width / 2 - licenseWindow.nativeWindow.width / 2;
+            licenseWindow.nativeWindow.y = this.nativeWindow.y + this.nativeWindow.height / 2 - licenseWindow.nativeWindow.height / 2;
+        }
 
-         private function openApacheFlexFolder(event:Event):void
-         {
-             _flexHomeDir.openWithDefaultApplication();
-         }
+        private function openApacheFlexFolder(event:Event):void
+        {
+            _flexHomeDir.openWithDefaultApplication();
+        }
 
-         private function closeApplication(event:Event):void
-         {
-             removeEventListener(Event.CLOSING, closeApplication);
+        private function closeApplication(event:Event):void
+        {
+            removeEventListener(Event.CLOSING, closeApplication);
 
-             if (currentState == "installState")
-             {
-                 if (currentStep < stepLabels.length)
-                 {
-                     // User aborted the installation by closing the installer
-                     var activeStep:StepItem = getActiveStepItem();
-                     if (_viewResourceConstants)
-                         abortInstallation(_viewResourceConstants.INFO_USER_ABORT_INSTALLATION + activeStep.label);
-                 }
-             }
+            if (currentState == "installState")
+            {
+                if (currentStep < stepLabels.length)
+                {
+                    // User aborted the installation by closing the installer
+                    var activeStep:StepItem = getActiveStepItem();
+                    if (_viewResourceConstants)
+                    {
+                        abortInstallation(_viewResourceConstants.INFO_USER_ABORT_INSTALLATION + activeStep.label);
+                    }
+                }
+            }
 
-             // TODO only enable close button when finished or when an error occurs
-             // TODO anything we need to clean up?
-             if (console && !console.closed)
-                 console.closeWindow(null);
-             cleanup();
-             close();
-         }
+            // TODO only enable close button when finished or when an error occurs
+            // TODO anything we need to clean up?
+            if (console && !console.closed)
+            {
+                console.closeWindow(null);
+            }
+            cleanup();
+            close();
+        }
 
-         protected function getActiveStepItem():StepItem
-         {
-             for each (var s:StepItem in _installationSteps)
-             {
-                 if (s.status == StepItem.ACTIVE)
-                 {
-                     return s;
-                 }
-             }
-             return null;
-         }
+        protected function getActiveStepItem():StepItem
+        {
+            for each (var s:StepItem in _installationSteps)
+            {
+                if (s.status == StepItem.ACTIVE)
+                {
+                    return s;
+                }
+            }
+            return null;
+        }
 
-         protected function clickLogo(event:MouseEvent):void
-         {
-             navigateToURL(new URLRequest(Constants.APACHE_FLEX_URL));
-         }
+        protected function clickLogo(event:MouseEvent):void
+        {
+            navigateToURL(new URLRequest(Constants.APACHE_FLEX_URL));
+        }
 
-         protected function getStepItemFromStepLabel(stepLabel:String):StepItem
-         {
-             for each (var s:StepItem in _installationSteps)
-             {
-                 if (s.label == stepLabel)
-                 {
-                     return s;
-                 }
-             }
+        protected function getStepItemFromStepLabel(stepLabel:String):StepItem
+        {
+            for each (var s:StepItem in _installationSteps)
+            {
+                if (s.label == stepLabel)
+                {
+                    return s;
+                }
+            }
 
-             return null;
-         }
+            return null;
+        }
 
-         protected function getInstallerComponentFromLabel(key:String):InstallerComponentVO
-         {
-             for each (var s:InstallerComponentVO in _installerComponentsDataProvider)
-             {
-                 if (s.key == key)
-                 {
-                     return s;
-                 }
-             }
+        protected function getInstallerComponentFromLabel(key:String):InstallerComponentVO
+        {
+            for each (var s:InstallerComponentVO in _installerComponentsDataProvider)
+            {
+                if (s.key == key)
+                {
+                    return s;
+                }
+            }
 
-             return null;
-         }
+            return null;
+        }
 
-         protected function updateActivityStep(stepLabel:String, status:String):void
-         {
-             var step:StepItem = getStepItemFromStepLabel(stepLabel);
+        protected function updateActivityStep(stepLabel:String, status:String):void
+        {
+            var step:StepItem = getStepItemFromStepLabel(stepLabel);
 
-             if (step)
-             {
-                 step.status = status;
-             }
-         }
+            if (step)
+            {
+                step.status = status;
+            }
+        }
 
-         private function isDirectoryEmpty(dir:File):Boolean
-         {
-             var result:Boolean;
+        private function isDirectoryEmpty(dir:File):Boolean
+        {
+            var result:Boolean;
 
-             var filesArray:Array = dir.getDirectoryListing();
+            var filesArray:Array = dir.getDirectoryListing();
 
-             var length:int = filesArray.length;
-             result = length == 0;
-             if (length == 1)
-             {
-                 var explodedPath:Array = File(filesArray[0]).url.split("/");
+            var length:int = filesArray.length;
+            result = length == 0;
+            if (length == 1)
+            {
+                var explodedPath:Array = File(filesArray[0]).url.split("/");
 
-                 // the .DS_Store file doesn't bother anybody, so we can safely ignore it.
-                 // also ignore local.properties so you an override install settings
-                 result = explodedPath[explodedPath.length - 1] == ".DS_Store" ||
-                 explodedPath[explodedPath.length - 1] == "local.properties";
-             }
+                // the .DS_Store file doesn't bother anybody, so we can safely ignore it.
+                // also ignore local.properties so you an override install settings
+                result = explodedPath[explodedPath.length - 1] == ".DS_Store" ||
+                        explodedPath[explodedPath.length - 1] == "local.properties";
+            }
 
-             return result;
-         }
+            return result;
+        }
 
-         protected function showDisclaimer():void
-         {
-             var request:URLRequest = new URLRequest(Constants.APACHE_FLEX_URL + Constants.DISCLAIMER_PATH);
+        protected function showDisclaimer():void
+        {
+            var request:URLRequest = new URLRequest(Constants.APACHE_FLEX_URL + Constants.DISCLAIMER_PATH);
 
-             navigateToURL(request, "_blank");
-         }
+            navigateToURL(request, "_blank");
+        }
 
-         protected function installComponentsList_creationCompleteHandler(event:FlexEvent):void
-         {
-             installComponentsList.addEventListener(InstallItemSelectionEvent.INSTALL_ITEM_SELECTION_CHANGED, handleInstallPermissionChange);
-         }
+        protected function installComponentsList_creationCompleteHandler(event:FlexEvent):void
+        {
+            installComponentsList.addEventListener(InstallItemSelectionEvent.INSTALL_ITEM_SELECTION_CHANGED, handleInstallPermissionChange);
+        }
 
-         private function onMouseRoll(event:MouseEvent):void
-         {
-             if (event.type == MouseEvent.MOUSE_OVER)
-             {
-                 event.target.styleName = "linkTextHover";
-             }
-             else
-             {
-                 event.target.styleName = "linkText";
-             }
-         }
+        private function onMouseRoll(event:MouseEvent):void
+        {
+            if (event.type == MouseEvent.MOUSE_OVER)
+            {
+                event.target.styleName = "linkTextHover";
+            }
+            else
+            {
+                event.target.styleName = "linkText";
+            }
+        }
 
-         private function getFlexVersionBuildString():String
-         {
-             var flexPropertiesFile:File = _flexHomeDir.resolvePath("flex-sdk-description.xml");
-             var fs:FileStream = new FileStream();
-             fs.open(flexPropertiesFile, FileMode.READ);
-             var contents:XML = new XML(fs.readMultiByte(fs.bytesAvailable, "utf-8"));
-             fs.close();
-             return contents.version + "." + contents.build;
-         }
-         ]]></fx:Script>
+        private function getFlexVersionBuildString():String
+        {
+            var flexPropertiesFile:File = _flexHomeDir.resolvePath("flex-sdk-description.xml");
+            var fs:FileStream = new FileStream();
+            fs.open(flexPropertiesFile, FileMode.READ);
+            var contents:XML = new XML(fs.readMultiByte(fs.bytesAvailable, "utf-8"));
+            fs.close();
+            return contents.version + "." + contents.build;
+        }
+        ]]></fx:Script>
     
     <fx:Declarations>
         <s:Sine id="ease"/>
@@ -3514,7 +3739,15 @@
             </s:layout>
         </s:DropDownList>
     </s:HGroup>
-
+    <!--    <s:Group width="100%" top="275">-->
+    <!--        <s:HGroup gap="0" horizontalCenter="0" top="30">
+    <s:Label text="apache" fontFamily="openSansBold" color="0x677084" fontSize="24" />
+    <s:Label text="Flex" right="0"
+    fontFamily="openSansBold"
+    color="0x172647" fontSize="70"
+    />
+    </s:HGroup>-->
+    
     <s:HGroup verticalAlign="middle" gap="5" horizontalCenter="0" top="300">
         <s:Label text="{_viewResourceConstants.INFO_VERSION}" fontFamily="openSansBold" color="0x677084" fontSize="24" />
         <s:Label text="{APACHE_FLEX_BIN_DISTRO_VERSION}" right="0"
@@ -3619,7 +3852,6 @@
                       styleName="mainBtnStyle"
                       width="{_standardButtonWidth}"
                       height="32"
-                      left="10"
                       label="{_viewResourceConstants.BTN_LABEL_BACK}"
                       enabled="true"
                       click="handleFirstStepBackBtnClick(event)"/>
@@ -3648,7 +3880,6 @@
                       styleName="mainBtnStyle"
                       width="{_standardButtonWidth}"
                       height="32"
-                      left="10"
                       label="{_viewResourceConstants.BTN_LABEL_BACK}"
                       enabled="true"
                       click="handleSecondStepBackBtnClick(event)"/>
@@ -3704,6 +3935,16 @@
                             editable="false"/>
             </s:VGroup>
         </s:HGroup>
+        <!--        <s:HGroup
+        width="100%"
+        height="20"
+        horizontalAlign="center"
+        verticalAlign="middle">
+        <s:CheckBox id="installChkBx"
+        label="{_viewResourceConstants.INSTALL_AGREE_ALL}"
+        selected="false" 
+        visible="true"/>
+        </s:HGroup>-->
     </s:Panel>
     <s:Panel id="thirdStepGroup"
              title="{_viewResourceConstants.INFO_INSTALLING}"
diff --git a/installer/src/org/apache/flex/packageflexsdk/util/ApacheURLLoader.as b/installer/src/org/apache/flex/packageflexsdk/util/ApacheURLLoader.as
new file mode 100644
index 0000000..07a85c4
--- /dev/null
+++ b/installer/src/org/apache/flex/packageflexsdk/util/ApacheURLLoader.as
@@ -0,0 +1,127 @@
+/**
+ 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.
+
+ */
+
+/**
+ *
+ * This is a really hackey way to intercept all the HTTPS calls and send them via
+ * as3httpdclient instead of the browser-captured URLLoader.  Don't follow this
+ * example -- refactor your application to avoid having to do this.
+ *
+ */
+package org.apache.flex.packageflexsdk.util
+{
+    import com.adobe.net.URI;
+
+    import flash.events.ErrorEvent;
+
+    import flash.events.Event;
+    import flash.events.HTTPStatusEvent;
+    import flash.events.IOErrorEvent;
+    import flash.events.SecurityErrorEvent;
+    import flash.net.URLLoader;
+    import flash.net.URLRequest;
+    import flash.utils.ByteArray;
+
+    import org.httpclient.HttpClient;
+    import org.httpclient.events.HttpDataListener;
+    import org.httpclient.events.HttpRequestEvent;
+    import org.httpclient.events.HttpResponseEvent;
+    import org.httpclient.events.HttpStatusEvent;
+
+    public class ApacheURLLoader extends URLLoader
+    {
+
+        private var httpsData:ByteArray = new ByteArray();
+
+        public function ApacheURLLoader(request:URLRequest = null)
+        {
+            super(request);
+        }
+
+        override public function load(request:URLRequest):void
+        {
+            if (request.url.indexOf("https://") != 0)
+            {
+                super.load(request);
+            }
+            else
+            {
+                var httpsClient:HttpClient = new HttpClient();
+                var httpsClientListener:HttpDataListener = new HttpDataListener();
+
+                httpsClientListener.onConnect = function(event:HttpRequestEvent):void
+                {
+                    var e:Event = new Event(Event.OPEN);
+                    dispatchEvent(e);
+                };
+
+                httpsClientListener.onComplete = function(event:HttpResponseEvent):void
+                {
+                    var e:HTTPStatusEvent = new HTTPStatusEvent(HTTPStatusEvent.HTTP_RESPONSE_STATUS);
+                    // we are unable to emulate the full event since the built-in event handlers for status and
+                    // many others are marked as private on the set functions.
+                    dispatchEvent(e);
+                };
+
+                httpsClientListener.onDataComplete = function(event:HttpResponseEvent, incomingData:ByteArray):void
+                {
+                    data = new ByteArray();
+                    data.writeBytes(incomingData);
+                    data.position=0;
+                    var e:Event = new Event(Event.COMPLETE);
+                    dispatchEvent(e);
+                };
+
+                httpsClientListener.onStatus = function(event:HttpStatusEvent):void
+                {
+                    var e:HTTPStatusEvent = new HTTPStatusEvent(HTTPStatusEvent.HTTP_STATUS);
+                    // we are unable to emulate the full event since the built-in event handlers for status and
+                    // many others are marked as private on the set functions.
+                    dispatchEvent(e);
+                };
+
+                httpsClientListener.onError = function(event:ErrorEvent):void
+                {
+                    var e:IOErrorEvent = new IOErrorEvent(IOErrorEvent.NETWORK_ERROR);
+                    e.text = event.text;
+                    dispatchEvent(e);
+                };
+
+                // ProgressEvent is not available in this manner.
+                // We can't emulate the HTTP Status Event.  It is internal to the Flash Player and won't
+                //    let us override the status item.
+
+                this.httpsData = new ByteArray();
+                httpsClient.get(new URI(request.url), httpsClientListener);
+            }
+
+        }
+
+        private function httpsSecurityError(event:SecurityErrorEvent):void
+        {
+            dispatchEvent(event.clone());
+        }
+
+        private function httpsIOError(event:IOErrorEvent):void
+        {
+            dispatchEvent(event.clone());
+        }
+
+    }
+
+}
