<?xml version="1.0" encoding="utf-8"?>
<!--

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 app should be used to create an Apache Flex SDK that has the
directory structure that an IDE expects.

The Adobe AIR SDK and the Adobe Flash Player playerglobal.swc are integrated
into the directory structure.  The paths in the framework configuration files are
modified to reflect this.  The AIR_HOME and PLAYERGLOBAL_HOME environment
variables are not required because the locations of these pieces are known.

-->


<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
                       xmlns:s="library://ns.adobe.com/flex/spark"
                       width="800" height="700" maxWidth="800" maxHeight="700" minWidth="800" minHeight="700"
                       backgroundColor="0xDDDDDD"
                       preinitialize="getInvoke()"
                       applicationComplete="handleApplicationComplete(event)" showStatusBar="false"
                       skinClass="ws.tink.spark.skins.controls.InstallApacheFlexSkin"
                       xmlns:controls="ws.tink.spark.controls.*"
                       xmlns:controls1="org.apache.flex.packageflexsdk.view.controls.*"
                       xmlns:components="org.apache.flex.packageflexsdk.view.components.*"
                       xmlns:controls2="org.apache.flex.utilities.common.controls.*">
    
    <fx:Style source="assets/styles/ApacheFlexToolsStyle.css"/>
    <fx:Style source="assets/styles/InstallApacheFlexStyle.css"/> 
    
    <fx:Declarations>
        <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>
                <s:VGroup left="10" top="10" right="10">
                    <s:CheckBox id="cb" label="Cache Downloaded Files" />
                    <s:HGroup width="100%" verticalAlign="baseline">
                        <s:Label text="Cache Folder: " />
                        <s:TextInput id="folder" width="100%" enabled="{cb.selected}"/>
                        <s:Button label="Browse..." click="browseFolders()" styleName="genericBtnStyle" enabled="{cb.selected}"/>
                    </s:HGroup>
                    <s:HGroup horizontalAlign="center" width="100%" >
                        <s:Button label="OK" click="updateCache()" enabled="{cb.selected == false || folder.text.length > 0}" styleName="genericBtnStyle" />
                        <s:Button label="Cancel" click="closeUp()" styleName="genericBtnStyle" />
                    </s:HGroup>
                </s:VGroup>
            </s:TitleWindow>
        </fx:Component>
    </fx:Declarations>
     <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 spark.events.IndexChangeEvent;
        import spark.events.TextOperationEvent;
        
        // 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.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;
        
        import ws.tink.spark.controls.StepItem;
        import ws.tink.spark.skins.controls.InstallApacheFlexSkin;
        
        // 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;
        
        private var cleanedUp:Boolean;
        
        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;
        
        public var installerAppPath:String;
        public var installerAppFileName: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:URLLoader;
        
        /**
         * Utility Singleton Instances
         */
        private var _md5CompareUtil:MD5CompareUtil = MD5CompareUtil.instance;
        private var _mirrorURLUtil:MirrorURLUtil = MirrorURLUtil.instance;
        
        /**
         * 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 = "";
        
        /**
         * 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;
        
        /**
         * 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;
        
        /**
         * Apache Flex
         *
         * Values stored in sdk-installer-config.xml edit file to change
         *
         */
        [Bindable] private var FLEX_VERSIONS:ArrayCollection = new ArrayCollection();
        
        /**
         *
         * SwfObject
         *
         */
        private var SWF_OBJECT_FILE:String;
        private var SWF_OBJECT_URL:String;
        
        /**
         * Optional installs
         *
         */
        private var OSMF_SWC_FILE:String;
        private var OSMF_SWC_URL:String;
        private var OSMF_SWF_FILE:String = "osmf.swf";
        
        private var BLAZEDS_FILE:String;
        private var BLAZEDS_URL: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;
        
        [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 _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 languageOverride:String;
        private var configOverride:String = "";
        private var stepsOverride:String = "";
        private var installOverride: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;
        
        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");
        
        [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 _lastTag:String;
        private var _lastPublicMessage:String;
        public function set lastPublicMessage(s:String):void
        {
            var tag:String;
            var c:int;
            
            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"));
        }
        
        [Bindable("messageChanged")]
        public function get lastFilteredPublicMessage():String
        {
            return _lastPublicMessage;
        }
        
        private function getInvoke():void
        {
            var nativeApplication:NativeApplication = NativeApplication.nativeApplication;
            nativeApplication.addEventListener(InvokeEvent.INVOKE, parseArgs);
        }
        
        [Bindable] private var _standardButtonWidth:Number = 88;
        
        public function setButtonWidths():void
        {
            var calc:CalcButtonWidth = new CalcButtonWidth(hiddenButton);
            
            calc.buttonWidth(installLogBtn);
            calc.buttonWidth(openApacheFlexFolderBtn);
            
            _standardButtonWidth = calc.maxButtonWidth([installBtn, browseBtn, closeBtn, nextBtn, firstStepBackBtn, secondStepBackBtn]);
        }
        
        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;
        }
        
        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 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());
            }
        }
        
        /**
         * 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 getIndexOfEnUS():int
        {
            for (var i:int = 0; i < _langSelect.dataProvider.length; i++)
            {
                if (_langSelect.dataProvider.getItemAt(i).data == "en_US")
                {
                    return i;
                }
            }
            return -1;
        }
        
        private function updateWindowTitle():void
        {
            if (_viewResourceConstants)
                this.nativeWindow.title = StringUtil.substitute(_viewResourceConstants.INFO_WINDOW_TITLE, [APACHE_FLEX_BIN_DISTRO_VERSION_DISPLAY]);
        }
        
        protected function selectDefaultLanguageInEmergency():void
        {
            loadLanguage("en_US", loadUSInEmergencyComplete);
        }
        
        private function loadUSInEmergencyComplete():void
        {
            _viewResourceConstants = ViewResourceConstants.instance;
            _viewResourceConstants.update();
        }
        
        protected function selectDefaultLanguage():void
        {
            loadLanguage("en_US", loadUSComplete);
        }

        private function loadUSComplete():void
        {
            var userLocale:String;
            
            if (userDefaultLanguage)
            {
                userLocale = userDefaultLanguage;
            }
            else
            {
                userLocale = new StringTools(LocaleID.DEFAULT).actualLocaleIDName.replace("-", "_");
            }
            
            if (languageOverride)
            {
                userLocale = languageOverride;
            }
            
            loadDefaultLanguage(userLocale);
        }
        
        private function loadDefaultLanguage(userLocale:String):void
        {
            loadLanguage(userLocale, defaultLanguageLoaded);
        }
        
        private var languageURL:String;
        private var languageID:String;
        
        private function loadLanguage(userLocale:String, completeFunction:Function):void
        {
            if (languageURL && loader) // busy loading another language
                loader.close();
            
            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 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;
                
                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;
                }
            }
            
            resourceManager.addResourceBundle(resource);
        }
        
        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 defaultLanguageLoaded():void
        {
            resourceManager.localeChain = [ ViewResourceConstants.DEFAULT_LANGUAGE ];
            
            var userLocale:String;
            
            if (userDefaultLanguage)
            {
                userLocale = userDefaultLanguage;
            }
            else
            {
                userLocale = new StringTools(LocaleID.DEFAULT).actualLocaleIDName.replace("-", "_");
            }
            
            if (languageOverride)
            {
                userLocale = languageOverride;
            }
            log("Using Locale: " + userLocale);
            
            var n:int = supportedLanguages.length;
            for (var i:int = 0; i < n; i++)
            {
                if (supportedLanguages[i].data == userLocale)
                {
                    _langSelect.selectedIndex = i;
                    
                    resourceManager.localeChain = [ userLocale, "en_US" ];
                    
                    break;
                }
            }
            _viewResourceConstants = ViewResourceConstants.instance;
            
            resourceManager.addEventListener(Event.CHANGE, _viewResourceConstants.update);
            
            _viewResourceConstants.update();
            setButtonWidths();
            directoryBtn.enabled = true;
            
            updateWindow();
            
            _mirrorURLUtil.logMessages = new LogMessagesVO(_viewResourceConstants.FETCH_MIRROR_CGI, _viewResourceConstants.FETCH_MIRROR_CGI_DONE,
                    _viewResourceConstants.FETCH_MIRROR_CGI_ERROR);
            
            _mirrorURLUtil.getMirrorURL(Constants.APACHE_FLEX_URL + _mirrorURLCGI, getMirrorURLResultHandler);
            CursorManager.removeBusyCursor();
            
            checkValidOS();
        }
        
        protected function updateWindow():void
        {
            updateWindowTitle();
            
            this.nativeWindow.x = Screen.mainScreen.bounds.width / 2 - this.nativeWindow.width / 2;
            this.nativeWindow.y = Screen.mainScreen.bounds.height / 2 - this.nativeWindow.height / 2;
        }
        
        protected function loadXML():void
        {
            var request:URLRequest;
            
            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);
            }
            
            _loader = new URLLoader();
            
            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);
            }
            
            _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);
        }
        
        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);
            }
        }
        
        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());
        }
        
        protected function xmlLoaded(event:Event):void
        {
            if (setXMLVariables()) {
                _langSelect.dataProvider = supportedLanguages;
                _langSelect.selectedIndex = getIndexOfEnUS();
                _langSelect.enabled = true;
                defineResourceManagerDefaultLanguage();
            }
        }
        
        protected function checkValidOS():void
        {
            if (_os.isOther())
                log(_viewResourceConstants.ERROR_UNSUPPORTED_OPERATING_SYSTEM);
        }
        
        private function devBuildFilterFunction(o:Object):Boolean
        {
            return !o.devBuild;
        }
        
        private function debugModeHandler(event:Event):void
        {
            debugMode = true;
            customMenuItem3.caption = "Verbose Logging Enabled";
        }
        
        private function debugProgressHandler(event:Event):void
        {
            logProgressEvents = true;
            customMenuItem4.caption = "Logging Progress Events";
        }
        
        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";
        }
        
        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 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();
        }
        
        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;
                
                _latestVersion = data.version.latest.toString();
                
                installerAppPath = data.installer.(@name == 'SDKInstallerApp').@path.toString();
                installerAppFileName = data.installer.(@name == 'SDKInstallerApp').@file.toString();
                
                _mirrorURLCGI = data.mirror.(@name == 'MirrorURLCGI').@file.toString();
                
                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);
                
                var contextMenuCustomItems:Array = ContextMenu(contextMenu).customItems;
                contextMenuCustomItems.push(customMenuItem1);
                contextMenuCustomItems.push(customMenuItem2);
                contextMenuCustomItems.push(customMenuItem3);
                contextMenuCustomItems.push(customMenuItem4);
                
                var name:String;
                var versionString:String;
                var versionID:String;
                
                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);
                }
                
                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});
                }
                
                if (this.airVersion.selectedIndex == -1) {
                    this.airVersion.selectedIndex = airVersions.indexOf(selected);
                }
                
                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});
                    }
                }
                
                FLEX_VERSIONS.filterFunction = devBuildFilterFunction;
                FLEX_VERSIONS.refresh();
                flexVersion.validateNow();
                
                if (this.flexVersion.selectedIndex == -1) {
                    this.flexVersion.selectedIndex = selectedFlexVersion;
                }
                
                var selectedFlexVersionObject:Object = this.flexVersion.selectedItem;
                updateFlexVersionStrings(selectedFlexVersionObject);
                
                if (!APACHE_FLEX_BIN_DISTRO_FILE || !APACHE_FLEX_BIN_DISTRO_PATH) {
                    log(_viewResourceConstants.ERROR_INVALID_SDK_URL);
                    keepGoing = false;
                }
                
                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});
                    }
                }
                
                if (this.flashPlayerVersion.selectedIndex == -1) {
                    this.flashPlayerVersion.selectedIndex = flashPlayerVersions.indexOf(selected);
                }
            }
            
            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;
            
            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;
            
            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;
            
            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;
            
            SWF_OBJECT_FILE = data.swfobject.@file.toString();
            SWF_OBJECT_URL = data.swfobject.@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;
            }
            
            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();
            
            AGLJ40_FILE = data.fontswf.aglj40.@file.toString();
            AGLJ40_URL = data.fontswf.aglj40.@path.toString();
            
            FLEX_FONTKIT_FILE = data.fontswf["flex-fontkit"].@file.toString();
            FLEX_FONTKIT_URL = data.fontswf["flex-fontkit"].@path.toString();
            
            RIDEAU_FILE = data.fontswf.rideau.@file.toString();
            RIDEAU_URL = data.fontswf.rideau.@path.toString();
            
            
            return keepGoing;
        }
        
        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;
            
            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";
            
            // 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 "";
        }
        
        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)));
            }
            
            if (_mirrorURLUtil.errorOccurred) {
                abortInstallation("mirrorURLUtil.errorOccurred");
                main();
            } else {
                updatePaths();
            }
            
        }
        
        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;
                }
            }
            
            if (installerAppPath.substr(0, Constants.URL_PREFIX.length) != Constants.URL_PREFIX) {
                installerAppPath = useMirrorPath(_mirrorURLUtil.mirrorURL) + installerAppPath;
            }
            
            main();
        }
        
        protected function main():void
        {
            
            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();
                
                // Log the Installer version to help with any support issues that arise.
                log("Installer version " + currentVersion + " (" + _os.os + ")", 0);
                loggedVersion = true;
            }
        }
        
        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();
            
            logVersion();
            
            var availBuildNumbers:Array = _latestVersion.split(".");
            var currentBuildNumbers:Array = currentVersion.split(".");
            
            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;
            
        }
        
        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 handleUpdaterDialogClose(event:Event):void
        {
            PopUpManager.removePopUp(IFlexDisplayObject(event.target));
        }
        
        protected function handleInstallBtnClick(event:MouseEvent):void
        {
			 var airVersionID:String = airVersion.selectedItem.versionID;
            var flashVersionID:String = flashPlayerVersion.selectedItem.versionID;
            
            log("SDK version " + APACHE_FLEX_BIN_DISTRO_VERSION_DISPLAY);
            
            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);
            }

            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 handleZeroStepNextBtnClick(event:MouseEvent):void
        {
            directoryBtn.enabled = false;
            
            AIR_VERSION = airVersion.selectedItem.version;
            var airVersionID:String = airVersion.selectedItem.versionID;
            FLASH_PLAYER_VERSION = flashPlayerVersion.selectedItem.version;
            var flashVersionID:String = flashPlayerVersion.selectedItem.versionID;
            
            setXMLVariables(); // as AIR and Flash version may of changed
            
            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, handleInstallerXMLError);
                
                loader.load(req);
            }
            else {
                showDirectoryState();
            }
        }
        
		protected function handleFirstStepBackBtnClick(event:MouseEvent):void
        {
            showDefaultState();
        }
        
        protected function handleSecondStepBackBtnClick(event:MouseEvent):void
        {
            showDirectoryState();
        }
		 
		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;
            }
            
            showOptionsState();
        }
        
        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;
            // 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";
        }
        
        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 handleInstallerXMLError(event:Event):void
        {
            log("Unable to load " + APACHE_FLEX_BIN_INSTALLER_URL);
            abortInstallation("Unable to load " + APACHE_FLEX_BIN_INSTALLER_URL);
        }
        
        protected function showDefaultState():void
        {
            zeroStepGroup.visible = true;
            directoryBtn.enabled = true;
            currentState = "default";
        }
        
        protected function showDirectoryState():void
        {
            initiateInstallStepsActivity();
            if (currentState != "optionsState")
            {
            initializeInstallerComponentsDataProvider();
            }
            currentState = "directoryState";
        }
        
        protected function showOptionsState():void
        {
            currentState = "optionsState";
            checkIfAllRequiredComponentsPromptsAnswered();
        }
        
        protected function initiateInstallStepsActivity():void
        {
            _installationSteps = new ArrayCollection();
            
            _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 resetInstallStepsActivity():void
        {
            for each(var step:StepItem in _installationSteps) {
                step.status = StepItem.NORMAL;
            }
        }
        
        protected function addOptionalComponentsToInstallSteps():void
        {
            if (usingXML)
            {
                _installationSteps = new ArrayCollection();
                
                _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));
                
                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 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 install():void
        {
            createDirectories();
        }
        
        protected function handleAirVersionChange(event:Event):void
        {
            AIR_VERSION = airVersion.selectedItem.version;
            
            // Match AIR and Flash versions
            if (flashPlayerVersion.selectedIndex != airVersion.selectedIndex) {
                flashPlayerVersion.selectedIndex = airVersion.selectedIndex;
                FLASH_PLAYER_VERSION = FLASH_PLAYER_VERSIONS[airVersion.selectedIndex].version;
            }
        }
        
        protected function handleFlashPlayerVersionChange(event:Event):void
        {
            FLASH_PLAYER_VERSION = flashPlayerVersion.selectedItem.version;
            
            // Match AIR and Flash versions
            if (airVersion.selectedIndex != flashPlayerVersion.selectedIndex) {
                airVersion.selectedIndex = flashPlayerVersion.selectedIndex;
                AIR_VERSION = AIR_VERSIONS[flashPlayerVersion.selectedIndex].version;
            }
        }
        
        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;
        }
        
        protected function browseForSDK(event:MouseEvent):void
        {
            var file:File = new File();
            
            file.addEventListener(Event.SELECT, flexSDKDirSelected, false, 0, true);
            file.browseForDirectory(_viewResourceConstants.INFO_SELECT_DIRECTORY);
        }
        
        protected function checkDirWritable(file:File):void
        {
            var ba:ByteArray = new ByteArray();
            ba.writeUTFBytes("1");
            writeFileToDirectory(file, ba);
            file.deleteFile();
        }
        
        protected function flexSDKDirSelected(event:Event):void
        {
            var selectedDir:File = File(event.target);
            var overlay:Boolean = flexVersion.selectedItem.overlay;
            
            // 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;
            }
           
            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;
            }
        }
        
        protected function handleFlexSDXTxtInputChange(event:TextOperationEvent):void
        {
            var tempDir:File;
            var path:String = flexSDKTxtInput.text;
            
            try {
                tempDir = new File(path);
                
                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);
            
            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 downloadApacheFlexSDK():void
        {
            updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_APACHE_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);
            }
            
        }
        
        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);
            }
            
            updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_APACHE_FLEX_SDK, StepItem.COMPLETE);
            
            updateActivityStep(_viewResourceConstants.STEP_VERIFY_FLEX_SDK, StepItem.ACTIVE);
            
            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 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);
        }
        
        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);
        }
        
        protected function uncompressApacheFlexSDK():void
        {
            if (!_md5CompareUtil.fileIsVerified) {
                updateActivityStep(_viewResourceConstants.STEP_VERIFY_FLEX_SDK, StepItem.ERROR);
                
                log(_viewResourceConstants.ERROR_VERIFY_FLEX_SDK);
                
                abortInstallation(_viewResourceConstants.ERROR_VERIFY_FLEX_SDK);
                return;
            } else {
                updateActivityStep(_viewResourceConstants.STEP_VERIFY_FLEX_SDK, StepItem.COMPLETE);
                
                log(_viewResourceConstants.INFO_VERIFY_FLEX_SDK_DONE);
            }
            
            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];
            
            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;
            }
            
            if (file.exists && !ant.processXMLFile(file, context, true))
            {
                ant.addEventListener(Event.COMPLETE, completeHandler);
                ant.addEventListener(ProgressEvent.PROGRESS, progressEventHandler);
            }
            else
                completeHandler(null);
        }
        
        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 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 (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 var ant:Ant;
        
        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);
        }
        
        private function enterFrameHandler(event:Event):void
        {
            ant.doCallback();
        }
        
        protected function downloadAIRRuntimeKitForWindows():void
        {
            updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK, StepItem.ACTIVE);
            
            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 downloadAIRRuntimeKitForMac():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();
            }
        }
        
        protected function downloadAIRRuntimeKitForLinux():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();
            }
        }
        
        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();
            }
            
            updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK, StepItem.COMPLETE);
            
            unzipAdobeAIRSDK();
        }
        
        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 unzipAdobeAIRSDK():void
        {
            updateActivityStep(_viewResourceConstants.STEP_UNZIP_AIR_RUNTIME_KIT, StepItem.ACTIVE);
            
            try {
                if (_os.isWindows()) {
                    unzipAdobeAIRSDKWindows()
                } else {
                    unzipAdobeAIRSDKMac();
                }
            } catch (e:Error) {
                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 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 handleAdobeAIRSDKMacUntarError(error:ProgressEvent = null):void
        {
            updateActivityStep(_viewResourceConstants.STEP_UNZIP_AIR_RUNTIME_KIT, StepItem.ERROR);
            abortInstallation();
        }
        
        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 handleAdobeAIRSDKWinZipFileUnzipComplete(event:Event):void
        {
            updateActivityStep(_viewResourceConstants.STEP_UNZIP_AIR_RUNTIME_KIT, StepItem.COMPLETE);
            log(_viewResourceConstants.INFO_FINISHED_UNZIPPING + _adobeAIRSDKZipFile.nativePath);
            downloadPlayerGlobalSWC();
        }
        
        protected function handleAdobeAIRSDKWinZipFileUnzipError(error:ErrorEvent = null):void
        {
            updateActivityStep(_viewResourceConstants.STEP_UNZIP_AIR_RUNTIME_KIT, StepItem.ERROR);
        }
        
        protected function downloadPlayerGlobalSWC():void
        {
            updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_FLASH_PLAYER_GLOBAL_SWC, StepItem.ACTIVE);
            
            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 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 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();
        }
        
        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 copyConfigFiles():void
        {
            var aborted:Boolean = false;
            
            updateActivityStep(_viewResourceConstants.STEP_INSTALL_CONFIG_FILES, StepItem.ACTIVE);
            
            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);
                
                for each (var file:File in configFiles) {
                    changeConfig(flexHomeFrameworksDir, file, FLASH_PLAYER_VERSION, FLASH_PLAYER_SWF_VERSION);
                }
                
                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;
            }
            
            if (!aborted) {
                updateActivityStep(_viewResourceConstants.STEP_INSTALL_CONFIG_FILES, StepItem.COMPLETE);
                downloadSwfObject();
            }
        }
        
        protected function downloadSwfObject():void
        {
            updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_SWFOBJECT, StepItem.ACTIVE);
            
            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 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 handleSWFObjectDownloadError(event:ErrorEvent = null):void
        {
            updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_SWFOBJECT, StepItem.ERROR);
            log(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_SWF_OBJECT);
            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"));
                
                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"));
                
                swfObjectJSFile.copyTo(_flexHomeDir.resolvePath("javascript" + File.separator + "FABridge" + File.separator + "samples" + File.separator
                    + "fabridge" + File.separator + "swfobject" + File.separator + "swfobject.js"));
                
                var swfObjectDir:File = _flexHomeDir.resolvePath("swfobject");
                swfObjectDir.deleteDirectory(true);
                
                updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_SWFOBJECT, StepItem.COMPLETE);
                installOSMF();
                
            } catch (e:Error) {
                updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_SWFOBJECT, StepItem.ERROR);
                log(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_SWF_OBJECT);
                abortInstallation();
            }
            
        }
        
        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 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 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 installFontSwf():void
        {
            updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, StepItem.ACTIVE);
            downloadFontSwfAFEFile();
        }
        
        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 handleFontSWFAFEFileDownloaded(event:Event):void
        {
            try {
                writeFileToDirectory(_afeJarFile, event.target.data);
                copyFileToOptionalLibDir(_afeJarFile);
                clearData(URLLoader(event.target));
                
                downloadFontSwfAGLFile();
                
            } 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 handleFontSWFAGLFileDownloaded(event:Event):void
        {
            try {
                writeFileToDirectory(_aglj40JarFile, event.target.data);
                copyFileToOptionalLibDir(_aglj40JarFile);
                clearData(URLLoader(event.target));
                
                downloadFontSwfFlexFontKitFile();
            } 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 handleFontSWFFlexFontKitFileDownloaded(event:Event):void
        {
            try {
                writeFileToDirectory(_flexFontKitJarFile, event.target.data);
                copyFileToOptionalLibDir(_flexFontKitJarFile);
                clearData(URLLoader(event.target));
                
                downloadFontSwfRideauKitFile();
            } 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 handleFontSWFRideauFileDownloaded(event:Event):void
        {
            try {
                writeFileToDirectory(_rideauJarFile, event.target.data);
                copyFileToOptionalLibDir(_rideauJarFile);
                clearData(URLLoader(event.target));
                
                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 installOSMF():void
        {
            updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, StepItem.ACTIVE);
            downloadOSMFFile();
        }
        
        protected function downloadOSMFFile():void
        {
            _osmfSWFFile = File.userDirectory.resolvePath(_flexTemp + File.separator + OSMF_SWF_FILE.toLowerCase());
            
            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 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 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('">'));
            
            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;
            
            var req:URLRequest = new URLRequest(mirrorURL);
            req.requestHeaders = [ new URLRequestHeader('Referer', refererURL) ];
            
            actuallyDownloadOSMF2SWC(req);
        }
        
        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);
            
            loader.load(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 handleOSMFSWCFileDownloaded(event:Event):void
        {
            try {
                writeFileToDirectory(_osmfSWCFile, event.target.data);
                copyFileToLibDir(_osmfSWCFile);
                unzip(_osmfSWCFile,handleOSMFSWCUnzipped,handleOSMFSWCUnzipError);
                clearData(URLLoader(event.target));
                
                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();
            }
        }
        
        /**
         * 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 handleOSMFSWCUnzipError(event:Event):void
        {
            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);
        }
        
        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 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 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 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 updateOptionalComponentInstallStatus(label:String, isInstalled:Boolean):void
        {
            for each (var obj:InstallerComponentVO in _installerComponentsDataProvider) {
                if (obj.label == label) {
                    obj.installed = isInstalled;
                }
            }
        }
        
        protected function updateOptionalComponentInstallStatusAborted(label:String, isAborted:Boolean):void
        {
            for each (var obj:InstallerComponentVO in _installerComponentsDataProvider) {
                if (obj.label == label) {
                    obj.aborted = isAborted;
                }
            }
        }
        
        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 cleanup(isAbort:Boolean = false, abortInfo:String = ""):void
        {
            if (cleanedUp)
                return;
            
            cleanedUp = true;
            
            CursorManager.removeBusyCursor();
            if (!_viewResourceConstants) {
                selectDefaultLanguageInEmergency();
            }
            try {
                if (_flexTempDir) {
                    _flexTempDir.deleteDirectory(true);
                }
            } catch (e:Error) {
                log(_viewResourceConstants.ERROR_UNABLE_TO_DELETE_TEMP_DIRECTORY);
            }
            
            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();
            }
            
            saveLogToDisk();
        }
        
        protected function saveLogToDisk():void
        {
            if (!_flexHomeDir) {
                return;
            }
            
            var file:File = _flexHomeDir.resolvePath("installer.log");
            var fs:FileStream = new FileStream();
            
            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 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 abortInstallation(reason:String = ""):void
        {
            if (currentState != "installState")
                showConsole(null);
            
            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;
        }
        
        protected function _langSelect_changeHandler(event:IndexChangeEvent):void
        {
            var defaultLanguage:String = ViewResourceConstants.DEFAULT_LANGUAGE;
            
            var so:SharedObject = SharedObject.getLocal("InstallApacheFlex");
            so.data.userDefaultLanguage = _langSelect.selectedItem["data"];
            so.flush();
            
            if (_langSelect.selectedItem["data"] == defaultLanguage)
            {
                resourceManager.localeChain = [ defaultLanguage ];
                resourceManager.update();
                setButtonWidths();
            }
            else
            {
                loadLanguage(_langSelect.selectedItem["data"], _langSelect_changeCompleteHandler);
            }
        }
        
        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();
            
            if (_viewResourceConstants) {
                rememberInstallerComponents();
                updateWindowTitle();
                initiateInstallStepsActivity();
                initializeInstallerComponentsDataProvider();
                recallInstallerComponents();
            }
        }
        
        private var _selectedInstallerComponents:Vector.<InstallerComponentVO>;
        
        protected function rememberInstallerComponents():void
        {
            _selectedInstallerComponents = new Vector.<InstallerComponentVO>;
            for each(var item:InstallerComponentVO in _installerComponentsDataProvider) {
                if (item.selected) {
                    _selectedInstallerComponents.push(item);
                }
            }
        }
        
        protected function recallInstallerComponents():void
        {
            for each(var item:InstallerComponentVO in _selectedInstallerComponents) {
                getInstallerComponentFromLabel(item.key).selected = true;
            }
        }
        
        protected function placeGroup(panel:Panel):void
        {
            panel.x = this.width / 2 - panel.width / 2;
        }
        
        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;
            }*/
            
            licenseLinkBtn.includeInLayout = true;
            _currentLicenseLabel = selectedItem.licenseName;
            _currentLicenseURL = selectedItem.licenseURL;
            checkIfAllRequiredComponentsPromptsAnswered();
            
        }
        
        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 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 *****************/
        
        private function createFolder(path:String):File
        {
            var dir:File = new File(path);
            
            if (!dir.exists)
                dir.createDirectory();
            
            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);
                
                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;
            
            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);
            
            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);
            
            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);
                
                progressBar.percent = percentLoaded;
            }
        }
        
        private function handleDownloadComplete(event:Event):void
        {
            _previousDisplayedPercent = 0;
            clearData(URLLoader(event.target));
        }
        
        private function clearData(v:URLLoader):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();
            
            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);
        }
        
        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;
                }
                
                fs.open(f, FileMode.WRITE);
                fs.writeBytes(fzf.content);
                fs.close();
                
            } 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 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>();
            
            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);
            
            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);
        }
        
        private function unTarError(event:Event):void
        {
            var output:String = _process.standardError.readUTFBytes(_process.standardError.bytesAvailable);
            
            log(_viewResourceConstants.ERROR_NATIVE_PROCESS_ERROR);
            log(output);
        }
        
        private function unTarFileProgress(event:Event):void
        {
            var output:String = _process.standardOutput.readUTFBytes(_process.standardOutput.bytesAvailable);
            
            log(output);
        }
        
        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 isValidConfigFile(file:File):Boolean
        {
            var name:String = file.name;
            
            if (name.search("-config.xml") == -1) {
                return false;
            } else {
                return true;
            }
        }
        
        private function isAirConfigFile(file:File):Boolean
        {
            var name:String = file.name;
            
            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 var console:ConsoleWindow;
        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;
        }
        
        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 openApacheFlexFolder(event:Event):void
        {
            _flexHomeDir.openWithDefaultApplication();
        }
        
        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);
                }
            }
            
            // 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 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;
                }
            }
            
            return null;
        }
        
        protected function getInstallerComponentFromLabel(key:String):InstallerComponentVO
        {
            for each (var s:InstallerComponentVO in _installerComponentsDataProvider) {
                if (s.key == key) {
                    return s;
                }
            }
            
            return null;
        }
        
        protected function updateActivityStep(stepLabel:String, status:String):void
        {
            var step:StepItem = getStepItemFromStepLabel(stepLabel);
            
            if (step) {
                step.status = status;
            }
        }
        
        private function isDirectoryEmpty(dir:File):Boolean
        {
            var result:Boolean;
            
            var filesArray:Array = dir.getDirectoryListing();
            
            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";
            }
            
            return result;
        }
        
        protected function showDisclaimer():void
        {
            var request:URLRequest = new URLRequest(Constants.APACHE_FLEX_URL + Constants.DISCLAIMER_PATH);
            
            navigateToURL(request, "_blank");
        }
        
        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 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"/>
        <s:BlurFilter id="blur"/>
    </fx:Declarations>
    
    <s:states>
        <s:State name="default"/>
        <s:State name="directoryState"/>
        <s:State name="optionsState"/>
        <s:State name="installState"/>
    </s:states>
    
    <s:transitions>
        <s:Transition id="showDefault" fromState="*" toState="default">
            <s:Sequence id="t0" targets="{[zeroStepGroup]}" effectEnd="placeGroup(zeroStepGroup)">
                <s:SetAction target="{zeroStepGroup}" property="visible" value="true"/>
                <s:SetAction target="{firstStepGroup}" property="visible" value="false"/>
                <s:SetAction target="{secondStepGroup}" property="visible" value="false"/>
                <s:SetAction target="{thirdStepGroup}" property="visible" value="false"/>
                <s:Move target="{zeroStepGroup}" xFrom="800" xTo="{this.width/2 - zeroStepGroup.width/2}" duration="500" easer="{ease}"/>
            </s:Sequence>
        </s:Transition>
        <s:Transition id="showDirectory" fromState="*" toState="directoryState">
            <s:Sequence id="t1" targets="{[firstStepGroup]}" effectEnd="placeGroup(firstStepGroup)">
                <s:SetAction target="{zeroStepGroup}" property="visible" value="false"/>
                <s:SetAction target="{firstStepGroup}" property="visible" value="true"/>
                <s:SetAction target="{secondStepGroup}" property="visible" value="false"/>
                <s:SetAction target="{thirdStepGroup}" property="visible" value="false"/>
                <s:Move target="{firstStepGroup}" xFrom="800" xTo="{this.width/2 - firstStepGroup.width/2}" duration="500" easer="{ease}"/>
            </s:Sequence>
        </s:Transition>
        <s:Transition id="showOptions" fromState="*" toState="optionsState">
            <s:Sequence id="t2" targets="{[secondStepGroup]}" effectEnd="placeGroup(secondStepGroup)">
                <s:SetAction target="{zeroStepGroup}" property="visible" value="false"/>
                <s:SetAction target="{firstStepGroup}" property="visible" value="false"/>
                <s:SetAction target="{secondStepGroup}" property="visible" value="true"/>
                <s:SetAction target="{thirdStepGroup}" property="visible" value="false"/>
                <s:Move target="{secondStepGroup}" xFrom="800" xTo="{this.width/2 - secondStepGroup.width/2}" duration="500" easer="{ease}"/>
            </s:Sequence>
        </s:Transition>
        <s:Transition id="showInstall" fromState="*" toState="installState">
            <s:Sequence id="t3" targets="{[thirdStepGroup]}" effectEnd="placeGroup(thirdStepGroup)">
                <s:SetAction target="{zeroStepGroup}" property="visible" value="false"/>
                <s:SetAction target="{firstStepGroup}" property="visible" value="false"/>
                <s:SetAction target="{secondStepGroup}" property="visible" value="false"/>
                <s:SetAction target="{thirdStepGroup}" property="visible" value="true"/>
                <s:Move target="{thirdStepGroup}" xFrom="800" xTo="{this.width/2 - thirdStepGroup.width/2}" duration="500" easer="{ease}"/>
            </s:Sequence>
        </s:Transition>
        <s:Transition id="backToDefault" fromState="directoryState" toState="default">
            <s:Sequence id="t4" targets="{[zeroStepGroup]}" effectEnd="placeGroup(zeroStepGroup)">
                <s:SetAction target="{zeroStepGroup}" property="visible" value="true"/>
                <s:SetAction target="{firstStepGroup}" property="visible" value="false"/>
                <s:SetAction target="{secondStepGroup}" property="visible" value="false"/>
                <s:SetAction target="{thirdStepGroup}" property="visible" value="false"/>
                <s:Move target="{zeroStepGroup}" xFrom="-800" xTo="{this.width/2 - zeroStepGroup.width/2}" duration="500" easer="{ease}"/>
            </s:Sequence>
        </s:Transition>
        <s:Transition id="backToDirectory" fromState="optionsState" toState="directoryState">
            <s:Sequence id="t5" targets="{[firstStepGroup]}" effectEnd="placeGroup(firstStepGroup)">
                <s:SetAction target="{zeroStepGroup}" property="visible" value="false"/>
                <s:SetAction target="{firstStepGroup}" property="visible" value="true"/>
                <s:SetAction target="{secondStepGroup}" property="visible" value="false"/>
                <s:SetAction target="{thirdStepGroup}" property="visible" value="false"/>
                <s:Move target="{firstStepGroup}" xFrom="-800" xTo="{this.width/2 - firstStepGroup.width/2}" duration="500" easer="{ease}"/>
            </s:Sequence>
        </s:Transition>
    </s:transitions>
    <s:layout>
        <s:BasicLayout/>
    </s:layout>
    <s:HGroup
        left="0"
        right="0"
        paddingLeft="20"
        paddingRight="20"
        paddingTop="5"
        horizontalAlign="right">
        <controls2:LinkButton
            text="{_viewResourceConstants.BTN_DISCLAIMER}"
            fontFamily="openSansSemibold"
            click="{showDisclaimer()}"
            />
        <s:Spacer width="100%"/>
        <s:Label id="langLabel"
                 horizontalCenter="0"
                 height="100%"
                 textAlign="right"
                 text="{_viewResourceConstants.INFO_CURRENT_LANGUAGE}"
                 fontFamily="openSansSemibold"
                 verticalAlign="middle"/>
        <s:DropDownList id="_langSelect"
                        enabled="false"
                        fontFamily="openSansSemibold"
                        change="_langSelect_changeHandler(event)">
            <s:layout>
                <s:VerticalLayout requestedRowCount="-1"/>
            </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"
                 fontFamily="openSansBold"
                 color="0x172647" fontSize="70"
                 />
    </s:HGroup>
    <!--    </s:Group>-->
    <s:Panel id="zeroStepGroup"
             title="{_viewResourceConstants.INFO_SELECT_AIR_FLASH_PLAYER}"
             width="640"
             height="200"
             top="380"
             x="{zeroStepGroup.x = this.width/2 - zeroStepGroup.width/2}"
             backgroundAlpha="0">
        <s:layout>
            <s:VerticalLayout
                verticalAlign="middle"
                horizontalAlign="center"
                paddingRight="10"
                paddingLeft="10"/>
        </s:layout>
        <s:HGroup verticalAlign="middle">
            <s:Label text="{_viewResourceConstants.INFO_SELECT_FLEX}" width="200" fontFamily="openSansBold" />
            <s:DropDownList id="flexVersion"
                            dataProvider="{FLEX_VERSIONS}"
                            labelField="label"
                            width="200"
                            fontFamily="openSansSemibold"
                            change="handleFlexVersionChange(event)">
                <s:layout>
                    <s:VerticalLayout requestedRowCount="-1"/>
                </s:layout>
            </s:DropDownList>
        </s:HGroup>
        <s:HGroup verticalAlign="middle">
            <s:Label text="{_viewResourceConstants.INFO_SELECT_AIR}" width="200" fontFamily="openSansBold" />
            <s:DropDownList id="airVersion"
                            dataProvider="{AIR_VERSIONS}"
                            width="200"
                            fontFamily="openSansSemibold"
                            change="handleAirVersionChange(event)">
                <s:layout>
                    <s:VerticalLayout requestedRowCount="-1"/>
                </s:layout>
            </s:DropDownList>
        </s:HGroup>
        <s:HGroup verticalAlign="middle">
            <s:Label text="{_viewResourceConstants.INFO_SELECT_FLASH}" width="200" fontFamily="openSansBold" />
            <s:DropDownList id="flashPlayerVersion"
                            width="200"
                            dataProvider="{FLASH_PLAYER_VERSIONS}"
                            fontFamily="openSansSemibold"
                            change="handleFlashPlayerVersionChange(event)">
                <s:layout>
                    <s:VerticalLayout requestedRowCount="-1"/>
                </s:layout>
            </s:DropDownList>
        </s:HGroup>
        <s:controlBarContent>
            <s:Spacer
                width="100%"/>
            <s:Button id="directoryBtn"
                      styleName="mainBtnStyle"
                      width="{_standardButtonWidth}"
                      height="32"
                      right="10"
                      label="{_viewResourceConstants.BTN_LABEL_NEXT}"
                      enabled="false"
                      click="handleZeroStepNextBtnClick(event)"/>
        </s:controlBarContent>
    </s:Panel>
    
    <s:Panel id="firstStepGroup"
             title="{_viewResourceConstants.INFO_SELECT_DIRECTORY_INSTALL}"
             width="640"
             height="200"
             top="380"
             x="{firstStepGroup.x = this.width/2 - firstStepGroup.width/2}"
             visible="false"
             visible.directoryState="true"
             backgroundAlpha="0">
        <s:layout>
            <s:HorizontalLayout
                verticalAlign="middle"
                paddingRight="10"
                paddingLeft="10"/>
        </s:layout>
        <s:TextInput id="flexSDKTxtInput"
                     width="100%"
                     prompt="{_viewResourceConstants.SELECT_PATH_PROMPT}"
                     change="handleFlexSDXTxtInputChange(event)"/>
        <s:Button id="browseBtn"
                  styleName="browseBtnStyle"
                  width="{_standardButtonWidth}"
                  height="32"
                  label="{_viewResourceConstants.BTN_LABEL_BROWSE}"
                  click="browseForSDK(event)"
                  toolTip="{_viewResourceConstants.INFO_SELECT_DIRECTORY}"/>
        <s:controlBarContent>
            <s:Button id="firstStepBackBtn"
                      styleName="mainBtnStyle"
                      width="{_standardButtonWidth}"
                      height="32"
                      left="10"
                      label="{_viewResourceConstants.BTN_LABEL_BACK}"
                      enabled="true"
                      click="handleFirstStepBackBtnClick(event)"/>
            <s:Spacer
                width="100%"/>
            <s:Button id="nextBtn"
                      styleName="mainBtnStyle"
                      width="{_standardButtonWidth}"
                      height="32"
                      right="10"
                      label="{_viewResourceConstants.BTN_LABEL_NEXT}"
                      enabled="false"
                      click="handleFirstStepNextBtnClick(event)"/>
        </s:controlBarContent>
    </s:Panel>
    <s:Panel id="secondStepGroup"
             title="{_viewResourceConstants.INFO_LICENSE_AGREEMENTS}"
             width="720"
             height="250"
             top="370"
             visible="false"
             visible.optionsState="true"
             backgroundAlpha="0"> 
        <s:controlBarContent>
            <s:Button id="secondStepBackBtn"
                      styleName="mainBtnStyle"
                      width="{_standardButtonWidth}"
                      height="32"
                      left="10"
                      label="{_viewResourceConstants.BTN_LABEL_BACK}"
                      enabled="true"
                      click="handleSecondStepBackBtnClick(event)"/>
            <s:Spacer
                width="100%"/>
            <s:Button id="installBtn"
                      styleName="mainBtnStyle"
                      width="{_standardButtonWidth}"
                      height="32"
                      right="10"
                      label="{_viewResourceConstants.BTN_LABEL_INSTALL}"
                      enabled="false"
                      click="handleInstallBtnClick(event)"/>
        </s:controlBarContent>
        <s:layout>
            <s:VerticalLayout
                verticalAlign="middle"
                paddingRight="10"
                paddingLeft="10"/>
        </s:layout>
        <s:HGroup
            width="100%"
            height="100%"
            horizontalAlign="center">
            <s:List id="installComponentsList"
                    width="50%"
                    height="100%"
                    horizontalScrollPolicy="off"
                    itemRenderer="org.apache.flex.packageflexsdk.view.itemrenderers.OptionalInstallItemRenderer"
                    dataProvider="{_installerComponentsDataProvider}"
                    change="handleOptionalInstallsChange(event)" creationComplete="installComponentsList_creationCompleteHandler(event)">
                <s:layout>
                    <s:VerticalLayout/>
                </s:layout>
            </s:List>
            <s:VGroup width="50%"
                      height="100%"
                      horizontalAlign="center"
                      gap="5">
                <controls2:LinkButton id="licenseLinkBtn"
                                      text="{_currentLicenseLabel}"
                                      fontWeight="bold"
                                      click="{handleLicenceBtnClick(event)}"
                                      paddingTop="5"
                                      includeInLayout="false"
                                      />
                <s:TextArea id="optionalInstallsTxtArea" text="{_viewResourceConstants.INFO_NEED_TO_READ_AND_AGREE_TO_LICENSE}"
                            fontFamily="openSansSemiBold"
                            fontSize="12"
                            width="100%"
                            height="100%"
                            verticalScrollPolicy="off"
                            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}"
             width="640"
             height="200"
             top="380"
             visible="false"
             visible.installState="true"
             backgroundAlpha="0">
        <s:layout>
            <s:VerticalLayout
                horizontalAlign="center"
                verticalAlign="middle"
                paddingTop="10"
                paddingRight="10"
                paddingLeft="10"
                gap="15"/>
        </s:layout>
        <controls1:MultiStepProgressIndicator
            steps="{_installationSteps}"/>
        <s:Label id="lastMessage"
                 text="{lastFilteredPublicMessage}"
                 fontFamily="openSansLightItalic"
                 textAlign="center"
                 width="80%" height="100%"
                 horizontalCenter="0"/>
        <controls:ProgressBar id="progressBar"
                              width="60%"
                              height="21"/>
        <s:Button id="openApacheFlexFolderBtn"
                  styleName="mainBtnStyle"
                  width="225"
                  height="32"
                  visible="false"
                  includeInLayout="false"
                  label="{_viewResourceConstants.BTN_LABEL_OPEN_APACHE_FLEX_FOLDER}"
                  toolTip="{_flexHome}"
                  click="openApacheFlexFolder(event)"/>
        <components:Tracker id="tracker" width="1" height="1" visible="false"/>
    </s:Panel>
    <s:HGroup
        left="0"
        right="0"
        bottom="20"
        paddingLeft="20"
        paddingRight="20"
        paddingTop="0"
        verticalAlign="middle">
        <s:Button id="installLogBtn"
                  styleName="genericBtnStyle"
                  width="110"
                  height="32"
                  label="{_viewResourceConstants.BTN_LABEL_INSTALL_LOG}"
                  click="showConsole(event)"/>
        <s:Spacer width="100%"/>
        <s:Label fontFamily="openSansLightItalic" text="{_viewResourceConstants.INFO_TRACKING}"
                 styleName="linkText" maxDisplayedLines="2"
                 mouseOver="onMouseRoll(event)" mouseOut="onMouseRoll(event)"
                 click="navigateToURL(new URLRequest('http://flex.apache.org/about-privacy.html'))"
                 buttonMode="true"
                 useHandCursor="true"
                 mouseChildren="false"/>
        <s:Spacer width="100%"/>
        <s:Button id="closeBtn"
                  styleName="genericBtnStyle"
                  width="{_standardButtonWidth}"
                  height="32"
                  label="{_viewResourceConstants.BTN_LABEL_CLOSE}"
                  click="closeApplication(event)"/>
    </s:HGroup>
    <!-- used to measure text -->
    <s:Button id="hiddenButton" visible="false" includeInLayout="false"/>
</s:WindowedApplication>
