<?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.controls.Alert;
        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 org.apache.flex.packageflexsdk.util.ApacheURLLoader;

        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 win64:Boolean;

        private var _mirrorURLCGI:String;
        private var _useMirror:Boolean = true;
        private var _latestVersion:String;
        private var installerVersion:String;
        private var loggedVersion:Boolean;
        private var logFile:String;
        private var debugMode:Boolean = false;
        private var logProgressEvents:Boolean = false;
        private var showDevBuilds:Boolean = false;
        private var usingDownloadCache:Boolean;
        private var downloadCacheFolder:String;
        private var userDefaultLanguage:String;
        private var firstTime:Boolean = true;
        private var legacy:Boolean = true;
        private var nocache:Boolean = true;
        private var wasAborted:Boolean;
        private var newSDKSelected:Boolean = true;

        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:ApacheURLLoader;

        /**
         * 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 = "";

        private var APACHE_FLEX_INSTALLER_PATH:String;
        private var APACHE_FLEX_INSTALLER_FILE: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:ApacheURLLoader;
        private var _process:NativeProcess;
        private var _previousDisplayedPercent:int = 0;
        private var _fileUnzipErrorFunction:Function;
        private var _numOptionalComponents:int = 4;
        private var _numOptionalComponentsPermissions:int = 0;
        private var _useOSMF2:Boolean = true;

        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 compList:XMLList;
        private var stepIDs:Vector.<String> = new Vector.<String>();
        private var stepLabels:Vector.<String> = new Vector.<String>();
        private var currentStep:int = 0;

        private var lastLicenseItemSelected: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("-64-bit-path=") == 0)
                {
                    APACHE_FLEX_INSTALLER_PATH = s.substring(13);
                }
                if (s.indexOf("-64-bit-file=") == 0)
                {
                    APACHE_FLEX_INSTALLER_FILE = s.substring(13);
                }
                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 ApacheURLLoader();
                    loader.dataFormat = URLLoaderDataFormat.TEXT;
                    loader.addEventListener(IOErrorEvent.IO_ERROR, languageLoadErrorHandler);
                    loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, languageLoadErrorHandler);
                    loader.addEventListener(Event.COMPLETE, function (e:Event):void
                    {
                        languageURL = null;
                        installLanguage(userLocale, loader.data);
                        completeFunction();
                    });
                    loader.load(url);
                    return;
                }
            }
            completeFunction();
        }

        private function 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 ApacheURLLoader();

            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();

            var installer:String = data.installer64.(@version == installerVersion).path.toString();;
            if (installer.length > 0)
                APACHE_FLEX_INSTALLER_PATH = installer;

            installer = data.installer64.(@version == installerVersion).file.toString();;
            if (installer.length > 0)
                APACHE_FLEX_INSTALLER_FILE = installer;

            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;
            }

            newSDKSelected = 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 (!win64 && shouldUpdate())
            {
                doUpdate();
            }
            else if (_os.os.indexOf("win") != -1 && !win64)
            {
                //32-bit Windows.  Try to use 64-bit version
                var app:File = new File(File.applicationStorageDirectory.nativePath + File.separator + "Win64" + File.separator + "Apache Flex SDK Installer.exe");
                if (!app.exists)
                {
                    Alert.show("This is the 32-bit Installer.  It will automatically download and upgrade to the 64-bit Installer",
                               "Upgrade to 64-bit Installer", Alert.OK, null, get64BitInstaller);
                }
                else
                    launch64();
            }

        }

        protected function get64BitInstaller(event:Event):void
        {
                var path64:String;
                if (APACHE_FLEX_INSTALLER_PATH.indexOf("://") == -1)
                    path64 = useMirrorPath(_mirrorURLUtil.mirrorURL) + APACHE_FLEX_INSTALLER_PATH + "/" + APACHE_FLEX_INSTALLER_FILE;
                else
                    path64 = APACHE_FLEX_INSTALLER_PATH + "/" + APACHE_FLEX_INSTALLER_FILE;
                copyOrDownload(path64, handle64BitInstaller, null, handle64BitInstallerError);
        }

        protected function handle64BitInstaller(event:Event):void
        {
            try
            {
                var app:File = new File(File.applicationStorageDirectory.nativePath + File.separator + APACHE_FLEX_INSTALLER_FILE);
                writeFileToDirectory(app, event.target.data);
                _flexHomeDir = new File(File.applicationStorageDirectory.nativePath + File.separator + "Win64");
                unzip(app, handle64BitUnzipComplete, handle64BitUnzipError);
            }
            catch (e:Error)
            {
               log("Unable to save" + app.nativePath);
               abortInstallation("handle64BitInstaller " + e.message);
            }

            log("downloaded " + APACHE_FLEX_INSTALLER_PATH + "/" + APACHE_FLEX_INSTALLER_FILE);
        }

        protected function handle64BitInstallerError(event:Event):void
        {
            log("Unable to install " + APACHE_FLEX_INSTALLER_PATH + "/" + APACHE_FLEX_INSTALLER_FILE);
            abortInstallation("Unable to install" + APACHE_FLEX_INSTALLER_PATH + "/" + APACHE_FLEX_INSTALLER_FILE);
        }

        private function launch64():void
        {
            Alert.show("This is the 32-bit Installer.  It will close and launch the 64-bit Installer",
                        "Launch 64-bit Installer", Alert.OK, null, actuallyLaunch64);
        }

        private function actuallyLaunch64(event:Event):void
        {
            try
            {
                var app:File = new File(File.applicationStorageDirectory.nativePath + File.separator + "Win64" + File.separator + "Apache Flex SDK Installer.exe");
                var startupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo();
                var args:Vector.<String> = new Vector.<String>();

                startupInfo.executable = app;
                startupInfo.arguments = args;

                var process:NativeProcess = new NativeProcess();
                process.start(startupInfo);
                NativeApplication.nativeApplication.exit();
            }
            catch (e:Error)
            {
               log("Unable to launch" + app.nativePath);
               abortInstallation("launch 64 " + e.message);
            }            
        }

        protected function handle64BitUnzipComplete(event:Event):void
        {
            launch64();
        }

        protected function handle64BitUnzipError(error:ErrorEvent = null):void
        {
            abortInstallation("Unable to unzip 64-bit Installer " + error.toString());
        }

        private function logVersion():void
        {
            if (!loggedVersion)
            {
                //Current version
                var applicationDescriptor:XML = NativeApplication.nativeApplication.applicationDescriptor;
                var xmlns:Namespace = new Namespace(applicationDescriptor.namespace());
                installerVersion = applicationDescriptor.xmlns::versionNumber.toString();
                var arch:String = applicationDescriptor.xmlns::architecture.toString();

                // Log the Installer version to help with any support issues that arise.
                if (_os.os.indexOf("win") != -1)
                {
                    log("Available Memory: " + System.totalMemory + " (" + arch + "-bit)", 0);
                    win64 = (arch == "64");
                }
                log("Installer version " + installerVersion + " (" + _os.os + ")", 0);
                log("Installer path: " + File.applicationDirectory.nativePath, 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)
            {
                if (newSDKSelected)
                {
                    var req:URLRequest = new URLRequest(APACHE_FLEX_BIN_INSTALLER_URL);
                    loader = new ApacheURLLoader();
                    loader.dataFormat = URLLoaderDataFormat.TEXT;
                    loader.addEventListener(Event.COMPLETE, handleInstallerXMLLoaded);
                    loader.addEventListener(ErrorEvent.ERROR, handleInstallerXMLError);
                    loader.addEventListener(IOErrorEvent.IO_ERROR, handleInstallerXMLError);

                    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();
            compList = data.component.copy();
            for each (var comp:XML in compList)
            {
                var vo:InstallerComponentVO = new InstallerComponentVO(getLocalizedString(comp, "label"),
                        getLocalizedString(comp, "message"), getLocalizedString(comp, "license"),
                        getLocalizedString(comp, "licenseURL"),
                        comp.@id.toString(), comp.@required.toString() == "true");
                licensePropertyMap[comp.@property.toString()] = vo;
                _installerComponentsDataProvider.addItem(vo);
            }
            usingXML = true;
            // progressLabels = data.progressLabels[0];
            installStepsData = data.steps.step;
            var strings:XMLList = data.strings.string;
            for each (var x:XML in strings)
            {
                var id:String = x.@id.toString();
                if (id in _viewResourceConstants)
                {
                    var val:String = getLocalizedString(x, null);
                    _viewResourceConstants[id] = val;
                    var pce:PropertyChangeEvent = PropertyChangeEvent.createUpdateEvent(this, id, "", val);
                    _viewResourceConstants.dispatchEvent(pce);
                }
            }
            var props:XMLList = data.properties.property;
            for each (x in props)
            {
                additionalProps[x.@name.toString()] = x.@value.toString();
            }
            currentState = "directoryState";
        }

        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
        {
            var versionNum:int = int(APACHE_FLEX_BIN_DISTRO_VERSION.split('.').join(''));
            _installerComponentsDataProvider = new ArrayCollection();
            /**
             * version 4.13.0 of the SDK is when the installer started using the new xml based
             * way of displaying/updating required or optional components of the installer
             */
            if (usingXML && (versionNum >= 4130))
            {
                for each (var comp:XML in compList)
                {
                    var vo:InstallerComponentVO = new InstallerComponentVO(getLocalizedString(comp, "label"),
                            getLocalizedString(comp, "message"), getLocalizedString(comp, "license"),
                            getLocalizedString(comp, "licenseURL"),
                            comp.@id.toString(), comp.@required.toString() == "true");
                    licensePropertyMap[comp.@property.toString()] = vo;
                    _installerComponentsDataProvider.addItem(vo);
                }
            }
            else
            {
                _installerComponentsDataProvider.addItem(new InstallerComponentVO(_viewResourceConstants.STEP_REQUIRED_INSTALL_APACHE_FLEX_SDK,
                        _viewResourceConstants.ASK_APACHE_FLEX, _viewResourceConstants.LICENSE_APACHE_V2,
                        _viewResourceConstants.LICENSE_URL_APACHE_V2,
                        "STEP_REQUIRED_INSTALL_APACHE_FLEX_SDK", true));
                _installerComponentsDataProvider.addItem(new InstallerComponentVO(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK,
                        _viewResourceConstants.ASK_ADOBE_AIR_SDK,
                        _viewResourceConstants.LICENSE_ADOBE_AIR_SDK,
                        _viewResourceConstants.LICENSE_URL_ADOBE_AIR_SDK,
                        "STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK", true));
                _installerComponentsDataProvider.addItem(new InstallerComponentVO(_viewResourceConstants.STEP_REQUIRED_INSTALL_FLASH_PLAYER_GLOBAL_SWC,
                        _viewResourceConstants.ASK_ADOBE_FLASH_PLAYER_GLOBAL_SWC,
                        _viewResourceConstants.LICENSE_ADOBE_SDK,
                        _viewResourceConstants.LICENSE_URL_ADOBE_SDK,
                        "STEP_REQUIRED_INSTALL_FLASH_PLAYER_GLOBAL_SWC", true));
                _installerComponentsDataProvider.addItem(new InstallerComponentVO(_viewResourceConstants.STEP_REQUIRED_INSTALL_SWFOBJECT,
                        _viewResourceConstants.ASK_SWFOBJECT,
                        _viewResourceConstants.LICENSE_SWFOBJECT,
                        _viewResourceConstants.LICENSE_URL_SWFOBJECT,
                        "STEP_REQUIRED_INSTALL_SWFOBJECT", true));
                _installerComponentsDataProvider.addItem(new InstallerComponentVO(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF,
                        _viewResourceConstants.ASK_OSMF,
                        _viewResourceConstants.LICENSE_OSMF,
                        _viewResourceConstants.LICENSE_URL_OSMF,
                        "STEP_REQUIRED_INSTALL_OSMF", true));
                _installerComponentsDataProvider.addItem(new InstallerComponentVO(_viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS,
                        _viewResourceConstants.ASK_BLAZEDS,
                        _viewResourceConstants.LICENSE_BLAZEDS,
                        _viewResourceConstants.LICENSE_URL_BLAZEDS,
                        "STEP_OPTIONAL_INSTALL_BLAZEDS", false));
                _installerComponentsDataProvider.addItem(new InstallerComponentVO(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF,
                        _viewResourceConstants.ASK_FONTSWF,
                        _viewResourceConstants.LICENSE_FONTSWF,
                        _viewResourceConstants.LICENSE_URL_FONTSWF,
                        "STEP_OPTIONAL_INSTALL_FONTSWF", false));
//              _installerComponentsDataProvider.addItem(new InstallerComponentVO(_viewResourceConstants.STEP_REQUIRED_INSTALL_OFL_FONTS,
//                      _viewResourceConstants.ASK_OFL_FONTS,
//                      _viewResourceConstants.LICENSE_OFL_FONTS,
//                      _viewResourceConstants.LICENSE_URL_OFL_FONTS,
//                      "STEP_REQUIRED_INSTALL_OFL_FONTS", true));
            }
        }

        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.validMD5)
            {
                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);
                }
            }
            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 + "&installerVersion=" + installerVersion);
                }
                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(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK + e.toString());
            }
        }

        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(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK + e.toString());
            }
        }

        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(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK + e.toString());
            }
        }

        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(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK + e.toString());
            }

            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(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_AIR_SDK);
        }

        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(_viewResourceConstants.STEP_UNZIP_AIR_RUNTIME_KIT + e.toString());
            }
        }

        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(_viewResourceConstants.STEP_UNZIP_AIR_RUNTIME_KIT);
        }

        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(_viewResourceConstants.STEP_REQUIRED_INSTALL_FLASH_PLAYER_GLOBAL_SWC + e.toString());
            }
        }

        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(_viewResourceConstants.STEP_REQUIRED_INSTALL_FLASH_PLAYER_GLOBAL_SWC + e.toString());
            }
            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(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_FLASH_PLAYER_SWC);
        }

        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(_viewResourceConstants.ERROR_UNABLE_TO_INSTALL_CONFIG_FILES);
                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(_viewResourceConstants.STEP_REQUIRED_INSTALL_SWFOBJECT + e.toString());
            }
        }

        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(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_SWF_OBJECT);
        }

        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(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_SWF_OBJECT);
            }

        }

        protected function handleSWFObjectZipFileUnzipError(event:Event):void
        {
            updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_SWFOBJECT, StepItem.ERROR);
            log(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_SWF_OBJECT);
            abortInstallation(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_SWF_OBJECT);
        }

        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(ApacheURLLoader(event.target));
                installNextOptionalComponent();
            }
            catch (e:Error)
            {
                updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS, StepItem.ERROR);
                updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS, true);
                installNextOptionalComponent();
            }
        }

        protected function 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(ApacheURLLoader(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(ApacheURLLoader(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(ApacheURLLoader(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(ApacheURLLoader(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 ApacheURLLoader();
            loader.dataFormat = URLLoaderDataFormat.BINARY;
            if (usingDownloadCache)
            {
                loader.addEventListener(Event.COMPLETE, cacheOSMF2SWC);
            }
            loader.addEventListener(Event.COMPLETE, handleOSMFSWCFileDownloaded);
            loader.addEventListener(ErrorEvent.ERROR, handleOSMFSWCInstallError);
            loader.addEventListener(IOErrorEvent.IO_ERROR, handleOSMFSWCInstallError);

            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(ApacheURLLoader(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(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF + e.toString());
            }
        }

        /**
         * 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(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF + e.toString());
            }
        }

        protected function handleOSMFSWCUnzipError(event:Event):void
        {
            updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, StepItem.ERROR);
            updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, true);
            abortInstallation(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF);
        }

        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 + "&installerVersion=" + installerVersion);
                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 + "&installerversion=" + installerVersion + "&info=" + abortInfo);
                if (_viewResourceConstants)
                {
                    log(_viewResourceConstants.INFO_ABORT_INSTALLATION + ": " + tracker.trackInstallerHTML.location);
                }
            }
            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;
            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();

                // This makes sure to update the Title of the license being displayed if the user changes languages
                _currentLicenseLabel = _installerComponentsDataProvider.getItemAt(lastLicenseItemSelected).licenseName;

            }
        }

        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;
             }*/

            // Store the current selected item in order to have the license title update if the language is changed
            lastLicenseItemSelected = installComponentsList.selectedIndex;

            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 ApacheURLLoader();
            if (debugMode)
            {
                log("downloading " + url);
                if (usingDownloadCache)
                {
                    log("using download cache");
                }
                if (nocache)
                {
                    log("not caching this download");
                }
            }
            if (usingDownloadCache && !nocache)
            {
                var cacheURL:String;
                if (_useMirror && url.indexOf(useMirrorPath(_mirrorURLUtil.mirrorURL)) != -1)
                {
                    cacheURL = url.substr(useMirrorPath(_mirrorURLUtil.mirrorURL).length);
                    if (debugMode)
                    {
                        log("mirror caching.  url = " + cacheURL);
                    }
                }
                else
                {
                    if (url.indexOf("http") == 0)
                    {
                        var c:int = url.indexOf("/");
                        c = url.indexOf("/", c + 1);
                        c = url.indexOf("/", c + 1);
                        // that should find the slash after the server.
                        cacheURL = url.substr(c + 1);
                        if (debugMode)
                        {
                            log("http caching.  url = " + cacheURL);
                        }
                    }
                }
                if (cacheURL)
                {
                    var cacheFile:File = File.applicationStorageDirectory.resolvePath(downloadCacheFolder);
                    cacheFile = cacheFile.resolvePath(escape(cacheURL));
                    if (debugMode)
                    {
                        log("searching cache for " + cacheFile.url);
                    }
                    if (cacheFile.exists)
                    {
                        log(_viewResourceConstants.INFO_USING_CACHED_FILE + " " + cacheFile.url);
                        url = cacheFile.url;
                    }
                }
            }
            var req:URLRequest = new URLRequest(url);
            //Wait for 5 minutes before aborting download attempt.  Adobe download sites as well as some Apache mirrors are extremely slow.
            req.idleTimeout = 300000;

            loader.dataFormat = URLLoaderDataFormat.BINARY;
            if (usingDownloadCache)
            {
                loader.addEventListener(Event.COMPLETE, function (event:Event):void
                {
                    if (debugMode)
                    {
                        log("download complete preparing to cache");
                    }
                    var cacheURL:String;
                    if (_useMirror && url.indexOf(useMirrorPath(_mirrorURLUtil.mirrorURL)) != -1)
                    {
                        cacheURL = url.substr(useMirrorPath(_mirrorURLUtil.mirrorURL).length);
                        if (debugMode)
                        {
                            log("mirror caching.  url = " + cacheURL);
                        }
                    }
                    else
                    {
                        if (url.indexOf("http") == 0)
                        {
                            var c:int = url.indexOf("/");
                            c = url.indexOf("/", c + 1);
                            c = url.indexOf("/", c + 1);
                            // that should find the slash after the server.
                            cacheURL = url.substr(c + 1);
                            if (debugMode)
                            {
                                log("http caching.  url = " + cacheURL);
                            }
                        }
                    }
                    if (cacheURL && !nocache)
                    {
                        var cacheFile:File = File.applicationStorageDirectory.resolvePath(downloadCacheFolder);
                        cacheFile = cacheFile.resolvePath(escape(cacheURL));
                        if (debugMode)
                        {
                            log("caching " + cacheFile.url);
                        }
                        if (!cacheFile.exists)
                        {
                            var fs:FileStream = new FileStream();
                            fs.open(cacheFile, FileMode.WRITE);
                            var srcData:ByteArray = ByteArray(loader.data);
                            srcData.position = 0;
                            var ba:ByteArray = new ByteArray();
                            srcData.readBytes(ba, 0, srcData.length);
                            ba.position = 0;
                            fs.writeBytes(ba, 0, ba.length);
                            fs.close();
                        }
                        else
                        {
                            if (debugMode)
                            {
                                log("file was already in cache");
                            }
                        }
                    }

                });
            }
            loader.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;
            }
            else
            {
                progressBar.percent = 100;
            }
        }

        private function handleDownloadComplete(event:Event):void
        {
            _previousDisplayedPercent = 0;
            clearData(ApacheURLLoader(event.target));
        }

        private function clearData(v:ApacheURLLoader):void
        {
            ByteArray(v.data).clear();
            System.gc();
        }

        private function unzip(fileToUnzip:File, unzipCompleteFunction:Function, unzipErrorFunction:Function = null):void
        {
            var zipFileBytes:ByteArray = new ByteArray();
            var fs:FileStream = new FileStream();
            var fzip:Zip = new Zip();

            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" && !wasAborted && !cleanedUp)
            {
                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
        {
            // try forcing GC before each step
            try {
                var lc1:LocalConnection = new LocalConnection();
                var lc2:LocalConnection = new LocalConnection();
                
                lc1.connect("name");
                lc2.connect("name");
            }
            catch (error:Error)
            {
            }
            
            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"
                      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"
                      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>
