<?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()" styleName="genericBtnStyle" />
                        <s:Button label="Cancel" click="closeUp()" styleName="genericBtnStyle" />
                    </s:HGroup>
                </s:VGroup>
            </s:TitleWindow>
        </fx:Component>
    </fx:Declarations>
	<fx:Script><![CDATA[
        import flash.globalization.LocaleID;
        import flash.globalization.StringTools;
        
        import mx.collections.ArrayCollection;
        import mx.core.IFlexDisplayObject;
        import mx.events.FlexEvent;
        import mx.events.PropertyChangeEvent;
        import mx.managers.CursorManager;
        import mx.managers.PopUpManager;        
        import mx.resources.ResourceBundle;
        import mx.rpc.events.FaultEvent;
        import mx.rpc.events.ResultEvent;
        import mx.rpc.http.HTTPService;
        import mx.utils.StringUtil;
        
        import spark.events.IndexChangeEvent;
        import spark.events.TextOperationEvent;
        
        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;
		
		private var _mirrorURLCGI:String;
		private var _useMirror:Boolean = true;
		private var _latestVersion:String;
		private var loggedVersion:Boolean;
        private var debugMode:Boolean = false;
        private var showDevBuilds:Boolean = false;
        private var usingDownloadCache:Boolean;
        private var downloadCacheFolder:String;
        private var firstTime:Boolean = true;
        private var legacy:Boolean = true;
        private var nocache: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:URLLoader;
        
		/**
		 * Utility Singleton Instances
		 */
		private var _md5CompareUtil:MD5CompareUtil = MD5CompareUtil.instance;
		private var _mirrorURLUtil:MirrorURLUtil = MirrorURLUtil.instance;
		
		/**
		 * Apache Flex binary distribution
		 *
		 * Values stored in sdk-installer-config.xml edit file to change
		 *
		 */
		private var APACHE_FLEX_BIN_DISTRO_PATH:String;
		private var APACHE_FLEX_BIN_DISTRO_FILE:String;
        private var APACHE_FLEX_BIN_INSTALLER_FILE:String;
		private var APACHE_FLEX_BIN_DISTRO_FILE_SHORT:String;
		private var APACHE_FLEX_BIN_DISTRO_URL:String;
        private var APACHE_FLEX_BIN_INSTALLER_URL:String;
		[Bindable] private var APACHE_FLEX_BIN_DISTRO_VERSION:String = "";
		[Bindable] private var APACHE_FLEX_BIN_DISTRO_VERSION_DISPLAY:String = "";
		
		/**
		 * Adobe AIR SDK
		 *
		 * Values stored in sdk-installer-config.xml edit file to change
		 *
		 */
		[Bindable] private var AIR_VERSIONS:ArrayCollection = new ArrayCollection();
		private var AIR_VERSION:String = "3.1";
		private var ADOBE_AIR_SDK_WIN_FILE:String;
		private var ADOBE_AIR_SDK_WIN_URL:String;
		private var ADOBE_AIR_SDK_MAC_FILE:String;
		private var ADOBE_AIR_SDK_MAC_URL:String;
		private var ADOBE_AIR_SDK_LINUX_FILE:String;
		private var ADOBE_AIR_SDK_LINUX_URL:String;
		
		/**
		 * Adobe Flash Player
		 *
		 * Values stored in sdk-installer-config.xml edit file to change
		 *
		 */
		[Bindable] private var FLASH_PLAYER_VERSIONS:ArrayCollection = new ArrayCollection();
		private var FLASH_PLAYER_VERSION:String = "11.1";
		private var FLASH_PLAYER_SWF_VERSION:String = "14";
		private var ADOBE_FB_GLOBALPLAYER_SWC_FILE:String;
		private var ADOBE_FB_GLOBALPLAYER_SWC_URL:String;
		
		/**
		 * Apache Flex
		 *
		 * Values stored in sdk-installer-config.xml edit file to change
		 *
		 */
		[Bindable] private var FLEX_VERSIONS:ArrayCollection = new ArrayCollection();
		
		/**
		 *
		 * SwfObject
		 *
		 */
		private var SWF_OBJECT_FILE:String;
		private var SWF_OBJECT_URL:String;
		
		/**
		 * Optional installs
		 *
		 */
		private var OSMF_SWC_FILE:String;
		private var OSMF_SWC_URL:String;
		private var OSMF_SWF_FILE:String = "osmf.swf";
		
		private var BLAZEDS_FILE:String;
		private var BLAZEDS_URL:String;
		
		private var AFE_FILE:String;
		private var AFE_URL:String;
		private var AGLJ40_FILE:String;
		private var AGLJ40_URL:String;
		private var FLEX_FONTKIT_FILE:String;
		private var FLEX_FONTKIT_URL:String;
		private var RIDEAU_FILE:String;
		private var RIDEAU_URL:String;
		
		[Bindable]
		private var _flexHome:String;
		private var _flexTemp:String;
		private var _flexHomeDir:File;
		private var _flexTempDir:File;
		private var _apacheFlexSDKCompressedFile:File;
		private var _adobeAIRSDKZipFile:File;
		private var _fbGlobalPlayerDir:File;
		private var _fbGlobalPlayerFile:File;
		private var _blazeDSJarFile:File;
		private var _afeJarFile:File;
		private var _aglj40JarFile:File;
		private var _flexFontKitJarFile:File;
		private var _rideauJarFile:File;
		private var _osmfSWCFile:File;
		private var _osmfSWFFile:File;
		
		private var _os:OS = new OS();
		private var _loader:URLLoader;
		private var _process:NativeProcess;
		private var _previousDisplayedPercent:int = 0;
		private var _fileUnzipErrorFunction:Function;
		private var _numOptionalComponents:int = 4;
		private var _numOptionalComponentsPermissions:int = 0;
		private var _useOSMF2:Boolean = true;
		
		private var languageOverride:String;
		private var configOverride:String = "";
        
        private var overlaying:Boolean;
        private var usingXML:Object;
        private var additionalProps:Object = {};
		private var licensePropertyMap:Object = {};
        private var progressLabels:XML;
        private var installStepsData:XMLList;
        private var stepIDs:Vector.<String> = new Vector.<String>();
        private var stepLabels:Vector.<String> = new Vector.<String>();
        private var currentStep:int = 0;
        
		[Bindable]
		private var _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]);
		}
		
		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("-debug") == 0) {
                    debugMode = true;
                }
			}
            var so:SharedObject = SharedObject.getLocal("InstallApacheFlex");
            usingDownloadCache = so.data.usingDownloadCache;
            downloadCacheFolder = so.data.downloadCacheFolder;
		}
		
		protected function handleApplicationComplete(event:FlexEvent):void {
            CursorManager.setBusyCursor();
            updateWindow();
			loadXML();
		}
		
		/**
		 * 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 selectDefaultLanguage():void {
            loadLanguage("en_US", loadUSComplete);
        }
        
        private function loadUSComplete():void
        {
            var userLocale:String = 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 function loadLanguage(userLocale:String, completeFunction:Function):void
        {
            var n:int = supportedLanguages.length;
            for (var i:int = 0; i < n; i++) {
                if (supportedLanguages[i].data == userLocale) {
                    var url:URLRequest = new URLRequest(supportedLanguages[i].path);
                    var urlLoader:URLLoader = new URLLoader();
                    urlLoader.dataFormat = URLLoaderDataFormat.TEXT;
                    urlLoader.addEventListener(IOErrorEvent.IO_ERROR, languageLoadErrorHandler);
                    urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, languageLoadErrorHandler);
                    urlLoader.addEventListener(Event.COMPLETE, function(e:Event):void {
                        installLanguage(userLocale, urlLoader.data);
                        completeFunction();
                        });
                    urlLoader.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();            
        }
        
        private function defaultLanguageLoaded():void {
            resourceManager.localeChain = [ ViewResourceConstants.DEFAULT_LANGUAGE ];
            
            var userLocale:String = 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();
			
            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();
		}
		
		protected function updateWindow():void {
			updateWindowTitle();
			
			this.nativeWindow.x = Screen.mainScreen.bounds.width / 2 - this.nativeWindow.width / 2;
			this.nativeWindow.y = Screen.mainScreen.bounds.height / 2 - this.nativeWindow.height / 2;
		}
		
		protected function loadXML():void {
			var request:URLRequest;
			
			if (configOverride != "") {
				request = new URLRequest(configOverride);
			} else {
				request = new URLRequest(Constants.APACHE_FLEX_URL + Constants.CONFIG_XML_NAME);
				//request = new URLRequest(Constants.CONFIG_XML_NAME);
			}
			
			_loader = new URLLoader();
			
			try {
				_loader.load(request);
			} catch (error:Error) {
				log("Unable to load " + Constants.APACHE_FLEX_URL + Constants.CONFIG_XML_NAME);
				log(_viewResourceConstants.ERROR_CONFIG_XML_LOAD + error.errorID + " " + error.message);
				abortInstallation();
			}
			
			_loader.addEventListener(IOErrorEvent.IO_ERROR, xmlError, false, 0, true);
			_loader.addEventListener(Event.COMPLETE, xmlLoaded, false, 0, true);
		}
		
		protected function xmlError(event:IOErrorEvent):void {
			log("Unable to load " + Constants.APACHE_FLEX_URL + Constants.CONFIG_XML_NAME);
			log(_viewResourceConstants.ERROR_CONFIG_XML_LOAD + event.errorID);
			abortInstallation();
		}
		
		protected function xmlLoaded(event:Event):void {
			checkValidOS();
			
			if (setXMLVariables()) {
                _langSelect.dataProvider = supportedLanguages;
                _langSelect.selectedIndex = getIndexOfEnUS();
                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;
        }
        
        private function devBuildShowHandler(event:Event):void
        {
            var item:Object = flexVersion.selectedItem;
            FLEX_VERSIONS.filterFunction = null;
            FLEX_VERSIONS.refresh();   
            flexVersion.selectedItem = item;
        }

        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 {
            var data:XML = XML(_loader.data);
            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();
                
                var customMenuItem1:ContextMenuItem = new ContextMenuItem("Show Dev Builds");
                customMenuItem1.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, devBuildShowHandler);
                var customMenuItem2:ContextMenuItem = new ContextMenuItem("Configure Download Cache");
                customMenuItem2.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, downloadCacheHandler);
                var customMenuItem3:ContextMenuItem = new ContextMenuItem("Enable Verbose Logging");
                customMenuItem3.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, debugModeHandler);
                
                var contextMenuCustomItems:Array = ContextMenu(contextMenu).customItems;
                contextMenuCustomItems.push(customMenuItem1);
                contextMenuCustomItems.push(customMenuItem2);
                contextMenuCustomItems.push(customMenuItem3);
                			
                var name:String;
                var versionString: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();
                    airVersions.push(versionString);
                    var airPath:String = airVersion.path.toString();
                    var airFile:String = airVersion.file.toString();
    				AIR_VERSIONS.addItem({label:"AIR " + displayVersion, version: versionString, 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();
                    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,
                                                                path: flashPath, file: flashFile});
    				}
    			}
    			
    			if (this.flashPlayerVersion.selectedIndex == -1) {
    				this.flashPlayerVersion.selectedIndex = flashPlayerVersions.indexOf(selected);	
    			}
            }
            
			ADOBE_AIR_SDK_WIN_FILE = data.airsdk.windows.versions.children().(@version==AIR_VERSION).file.toString();
			ADOBE_AIR_SDK_WIN_URL = data.airsdk.windows.versions.children().(@version==AIR_VERSION).path.toString();
			if (_os.isWindows() && (!ADOBE_AIR_SDK_WIN_FILE || !ADOBE_AIR_SDK_WIN_URL)) {
				log(_viewResourceConstants.ERROR_INVALID_AIR_SDK_URL_WINDOWS);
				keepGoing = false;
			}
			ADOBE_AIR_SDK_WIN_URL += ADOBE_AIR_SDK_WIN_FILE;
			
			ADOBE_AIR_SDK_MAC_FILE = data.airsdk.mac.versions.children().(@version==AIR_VERSION).file.toString();
			ADOBE_AIR_SDK_MAC_URL = data.airsdk.mac.versions.children().(@version==AIR_VERSION).path.toString();
			if (_os.isMac() && (!ADOBE_AIR_SDK_MAC_FILE || !ADOBE_AIR_SDK_MAC_URL)) {
				log(_viewResourceConstants.ERROR_INVALID_AIR_SDK_URL_MAC);
				keepGoing = false;
			}
			ADOBE_AIR_SDK_MAC_URL += ADOBE_AIR_SDK_MAC_FILE;
			
			ADOBE_AIR_SDK_LINUX_FILE = data.airsdk.linux.versions.children().(@version==AIR_VERSION).file.toString();
			ADOBE_AIR_SDK_LINUX_URL = data.airsdk.linux.versions.children().(@version==AIR_VERSION).path.toString();
			if (_os.isLinux() && (!ADOBE_AIR_SDK_LINUX_FILE || !ADOBE_AIR_SDK_LINUX_URL)) {
				log(_viewResourceConstants.ERROR_INVALID_AIR_SDK_URL_LINUX);
				keepGoing = false;
			}
			ADOBE_AIR_SDK_LINUX_URL += ADOBE_AIR_SDK_LINUX_FILE;
			
			ADOBE_FB_GLOBALPLAYER_SWC_FILE = data.flashsdk.versions.children().(@version==FLASH_PLAYER_VERSION).file.toString();
			ADOBE_FB_GLOBALPLAYER_SWC_URL = data.flashsdk.versions.children().(@version==FLASH_PLAYER_VERSION).path.toString();
			FLASH_PLAYER_SWF_VERSION = data.flashsdk.versions.children().(@version==FLASH_PLAYER_VERSION).swfversion.toString();
			if (!ADOBE_FB_GLOBALPLAYER_SWC_FILE || !ADOBE_FB_GLOBALPLAYER_SWC_URL) {
				log(_viewResourceConstants.ERROR_INVALID_FLASH_PLAYER_SWC_URL);
				keepGoing = false;
			}
			ADOBE_FB_GLOBALPLAYER_SWC_URL += ADOBE_FB_GLOBALPLAYER_SWC_FILE;
			
			SWF_OBJECT_FILE = data.swfobject.@file.toString();
			SWF_OBJECT_URL = data.swfobject.@path.toString();
			
			//Supporting OSMF 2.0 from 4.11 onwards.  
			if(APACHE_FLEX_BIN_DISTRO_VERSION == "4.9.1" || APACHE_FLEX_BIN_DISTRO_VERSION == "4.10.0" )
			{
				OSMF_SWC_FILE = data.OSMF_SWC.@file.toString();
				OSMF_SWC_URL = data.OSMF_SWC.@path.toString();
				_useOSMF2 = false;
			}
			else
			{
				OSMF_SWC_FILE = data["OSMF_SWC_2.0"].@file.toString();
				OSMF_SWC_URL = data["OSMF_SWC_2.0"].@path.toString();
				_useOSMF2 = true;
			}
			
			BLAZEDS_FILE = data.BlazeDS.@file.toString();
			BLAZEDS_URL = data.BlazeDS.@path.toString();
			
			AFE_FILE = data.fontswf.afe.@file.toString();
			AFE_URL = data.fontswf.afe.@path.toString();
			
			AGLJ40_FILE = data.fontswf.aglj40.@file.toString();
			AGLJ40_URL = data.fontswf.aglj40.@path.toString();
			
			FLEX_FONTKIT_FILE = data.fontswf["flex-fontkit"].@file.toString();
			FLEX_FONTKIT_URL = data.fontswf["flex-fontkit"].@path.toString();
			
			RIDEAU_FILE = data.fontswf.rideau.@file.toString();
			RIDEAU_URL = data.fontswf.rideau.@path.toString();
			
			
			return keepGoing;
		}
		
		protected function updateFlexVersionStrings(selectedFlexVersionObject:Object):void
		{
			APACHE_FLEX_BIN_DISTRO_FILE_SHORT = selectedFlexVersionObject.shortName;
			APACHE_FLEX_BIN_DISTRO_VERSION = selectedFlexVersionObject.version;
			APACHE_FLEX_BIN_DISTRO_VERSION_DISPLAY = selectedFlexVersionObject.label;
			
			APACHE_FLEX_BIN_DISTRO_FILE = selectedFlexVersionObject.fileName;
			APACHE_FLEX_BIN_DISTRO_PATH = selectedFlexVersionObject.path;
			legacy =  selectedFlexVersionObject.legacy;
            nocache = selectedFlexVersionObject.nocache;
            APACHE_FLEX_BIN_INSTALLER_FILE = selectedFlexVersionObject.prefix + "installer-config.xml";
            
			// ApacheFlex is full URL so download directly and dont use mirror useful for testing release candidates
			if (APACHE_FLEX_BIN_DISTRO_PATH.indexOf("http") == 0) {
				_useMirror = false;
			}
			else
			{
				_useMirror = true;
			}
		}
		
		private function useMirrorPath(path:String):String {
			if (_useMirror) {
				return path;
			}
			
			return "";
		}
		
		private function getMirrorURLResultHandler():void {
			var logMessages:ArrayCollection = ILog(_mirrorURLUtil).log;
			var i:int;
			var n:int = logMessages.length;
			for (i = 0; i < n; i++) {
				log(String(logMessages.getItemAt(i)));
			}
			
			if (_mirrorURLUtil.errorOccurred) {
				abortInstallation();
                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;
                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;
                APACHE_FLEX_BIN_INSTALLER_URL = MD5CompareUtil.MD5_DOMAIN + APACHE_FLEX_BIN_DISTRO_PATH + APACHE_FLEX_BIN_INSTALLER_FILE;
            }
            
            if (installerAppPath.substr(0, Constants.URL_PREFIX.length) != Constants.URL_PREFIX) {
                installerAppPath = useMirrorPath(_mirrorURLUtil.mirrorURL) + installerAppPath;
            }
            
            main();
        }
        
		protected function main():void {
			
			if (shouldUpdate()) {
				doUpdate();
			}
		}
		
		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();
			
            if (!loggedVersion)
            {
    			// Log the Installer version to help with any support issues that arise.
    			log("Version " + currentVersion + " (" + _os.os + ")", 0);
                loggedVersion = true;
            }
            
			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 {
			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 {	
			AIR_VERSION = airVersion.selectedItem.version;
			FLASH_PLAYER_VERSION = flashPlayerVersion.selectedItem.version;
			
			setXMLVariables(); // as AIR and Flash version may of changed
			
			log("AIR version " + AIR_VERSION);
			log("Flash Player version " + FLASH_PLAYER_VERSION);
			
            if (!legacy)
            {
                var req:URLRequest = new URLRequest(APACHE_FLEX_BIN_INSTALLER_URL);
                loader = new URLLoader();
                loader.dataFormat = URLLoaderDataFormat.TEXT;
                loader.addEventListener(Event.COMPLETE, handleInstallerXMLLoaded);
                loader.addEventListener(ErrorEvent.ERROR, handleInstallerXMLError);
                loader.addEventListener(IOErrorEvent.IO_ERROR, handleInstallerXMLError);
                
                loader.load(req);          
            }
            else
                showDirectoryState();
		}
		
		protected function handleFirstStepNextBtnClick(event:MouseEvent):void {
            showOptionsState();
        }
        
        protected function handleInstallerXMLLoaded(event:Event):void {
            var data:XML = XML(event.target.data);
            var localeList:Array = resourceManager.localeChain;
            _installerComponentsDataProvider = new ArrayCollection();
            var compList:XMLList = data.component;
            for each (var comp:XML in compList)
            {
                var vo:InstallerComponentVO = new InstallerComponentVO(getLocalizedString(comp, "label"),
                    getLocalizedString(comp, "message"), getLocalizedString(comp, "license"),
                    getLocalizedString(comp, "licenseURL"),
                    comp.@id.toString(), comp.@required.toString() == "true");
                licensePropertyMap[comp.@property.toString()] = vo;
                _installerComponentsDataProvider.addItem(vo);
            }
            usingXML = true;
            // progressLabels = data.progressLabels[0];
            installStepsData = data.steps.step;
            var strings:XMLList = data.strings.string;
            for each (var x:XML in strings)
            {
                var id:String = x.@id.toString();
                if (id in _viewResourceConstants)
                {
                    var val:String = getLocalizedString(x, null);
                    _viewResourceConstants[id] = val;
                    var pce:PropertyChangeEvent = PropertyChangeEvent.createUpdateEvent(this, id, "", val);
                    _viewResourceConstants.dispatchEvent(pce);
                }
            }
            var props:XMLList = data.properties.property;
            for each (x in props)
            {
                additionalProps[x.@name.toString()] = x.@value.toString();
            }
            currentState = "directoryState";
        }
        
        private function getLocalizedString(xml:XML, propName:String):String
        {
            var compBundle:XMLList;
            for each (var locale:String in resourceManager.localeChain)
            {
                compBundle = xml[locale];
                if (compBundle.length() == 1)
                {
                    if (propName)
                    {
                        var xmlList:XMLList = compBundle[0][propName];
                        if (xmlList.length() == 1)
                        {
                            return xmlList[0].toString();
                        }
                    }
                    else
                    {
                        var s:String = compBundle[0].toString();
                        if (s.length > 0)
                            return s;
                    }
                }
            }
            return "";
        }
        
        protected function handleInstallerXMLError(event:Event):void {
            showDirectoryState();
        }
        
        protected function showDirectoryState():void
        {
            initiateInstallStepsActivity();
            initializeInstallerComponentsDataProvider();
            
            currentState = "directoryState";
        }
        
        protected function showOptionsState():void {
			currentState = "optionsState";
		}
		
		protected function initiateInstallStepsActivity():void {
			_installationSteps = new ArrayCollection();
			
			_installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_CREATE_DIRECTORIES));
			_installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_REQUIRED_INSTALL_APACHE_FLEX_SDK));
			_installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_VERIFY_FLEX_SDK));
			_installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_UNZIP_FLEX_SDK));
			_installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK));
			_installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_UNZIP_AIR_RUNTIME_KIT));
			_installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_REQUIRED_INSTALL_FLASH_PLAYER_GLOBAL_SWC));
			_installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_INSTALL_CONFIG_FILES));
			_installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_REQUIRED_INSTALL_SWFOBJECT));
			_installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF));
		}
		
		protected function resetInstallStepsActivity():void {
			for each(var step:StepItem in _installationSteps) {
				step.status = StepItem.NORMAL;
			}
		}
		
		protected function addOptionalComponentsToInstallSteps():void {
            if (usingXML)
            {
                _installationSteps = new ArrayCollection();

                _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_CREATE_DIRECTORIES));
                _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_REQUIRED_INSTALL_APACHE_FLEX_SDK));
                _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_VERIFY_FLEX_SDK));
                _installationSteps.addItem(new StepItem(_viewResourceConstants.STEP_UNZIP_FLEX_SDK));

                for each (var stepData:XML in installStepsData) {
                    var propName:String = stepData.@property.toString();
                    if (!propName || InstallerComponentVO(licensePropertyMap[propName]).selected)
                    {
                        var si:StepItem = new StepItem(getLocalizedString(stepData, null));
                        _installationSteps.addItem(si);
                        stepIDs.push(stepData.@id.toString());
                        stepLabels.push(si.label);
                    }
                }
                return;
            }
			for each (var obj:InstallerComponentVO in _installerComponentsDataProvider) {
				if (!obj.required && obj.selected) {
					_installationSteps.addItem(new StepItem(obj.label));
				}
			}
		}
		
		protected function initializeInstallerComponentsDataProvider():void {
			_installerComponentsDataProvider = new ArrayCollection();
			_installerComponentsDataProvider.addItem(new InstallerComponentVO(_viewResourceConstants.STEP_REQUIRED_INSTALL_APACHE_FLEX_SDK,
				_viewResourceConstants.ASK_APACHE_FLEX, _viewResourceConstants.LICENSE_APACHE_V2,
				_viewResourceConstants.LICENSE_URL_APACHE_V2,
				"STEP_REQUIRED_INSTALL_APACHE_FLEX_SDK", true));
			_installerComponentsDataProvider.addItem(new InstallerComponentVO(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK,
				_viewResourceConstants.ASK_ADOBE_AIR_SDK,
				_viewResourceConstants.LICENSE_ADOBE_AIR_SDK,
				_viewResourceConstants.LICENSE_URL_ADOBE_AIR_SDK,
				"STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK", true));
			_installerComponentsDataProvider.addItem(new InstallerComponentVO(_viewResourceConstants.STEP_REQUIRED_INSTALL_FLASH_PLAYER_GLOBAL_SWC,
				_viewResourceConstants.ASK_ADOBE_FLASH_PLAYER_GLOBAL_SWC,
				_viewResourceConstants.LICENSE_ADOBE_SDK,
				_viewResourceConstants.LICENSE_URL_ADOBE_SDK,
				"STEP_REQUIRED_INSTALL_FLASH_PLAYER_GLOBAL_SWC", true));
			_installerComponentsDataProvider.addItem(new InstallerComponentVO(_viewResourceConstants.STEP_REQUIRED_INSTALL_SWFOBJECT,
				_viewResourceConstants.ASK_SWFOBJECT, _viewResourceConstants.LICENSE_SWFOBJECT,
				_viewResourceConstants.LICENSE_URL_SWFOBJECT, "STEP_REQUIRED_INSTALL_SWFOBJECT",
				true));
			_installerComponentsDataProvider.addItem(new InstallerComponentVO(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF,
				_viewResourceConstants.ASK_OSMF, _viewResourceConstants.LICENSE_OSMF,
				_viewResourceConstants.LICENSE_URL_OSMF, "STEP_REQUIRED_INSTALL_OSMF", true));
			_installerComponentsDataProvider.addItem(new InstallerComponentVO(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF,
				_viewResourceConstants.ASK_FONTSWF, _viewResourceConstants.LICENSE_FONTSWF,
				_viewResourceConstants.LICENSE_URL_FONTSWF, "STEP_OPTIONAL_INSTALL_FONTSWF",
				false));
			_installerComponentsDataProvider.addItem(new InstallerComponentVO(_viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS,
				_viewResourceConstants.ASK_BLAZEDS, _viewResourceConstants.LICENSE_BLAZEDS,
				_viewResourceConstants.LICENSE_URL_BLAZEDS, "STEP_OPTIONAL_INSTALL_BLAZEDS",
				false));
		}
		
		protected function install():void {
			createDirectories();
		}
		
		protected function handleAirVersionChange(event:Event):void {
			AIR_VERSION = airVersion.selectedItem.version;
			
			// Match AIR and Flash versions
			if (flashPlayerVersion.selectedIndex != airVersion.selectedIndex) {
				flashPlayerVersion.selectedIndex = airVersion.selectedIndex;
				FLASH_PLAYER_VERSION = FLASH_PLAYER_VERSIONS[airVersion.selectedIndex].version;
			}
		}
		
		protected function handleFlashPlayerVersionChange(event:Event):void {
			FLASH_PLAYER_VERSION = flashPlayerVersion.selectedItem.version;
			
			// Match AIR and Flash versions
			if (airVersion.selectedIndex != flashPlayerVersion.selectedIndex) {
				airVersion.selectedIndex = flashPlayerVersion.selectedIndex;
				AIR_VERSION = AIR_VERSIONS[flashPlayerVersion.selectedIndex].version;
			}
		}
		
		protected function handleFlexVersionChange(event:Event):void {
			/*APACHE_FLEX_BIN_DISTRO_VERSION =  flexVersion.selectedItem.version;
			APACHE_FLEX_BIN_DISTRO_VERSION_DISPLAY = flexVersion.selectedItem.label;*/
            var item:Object = flexVersion.selectedItem;
            airVersion.enabled = item.needsAIR;
            flashPlayerVersion.enabled = item.needsFlash;
			updateFlexVersionStrings(item);
			updatePaths();
			updateWindowTitle();
            InstallApacheFlexSkin(skin).textIcon.source = item.icon;
		}
		
		protected function browseForSDK(event:MouseEvent):void {
			var file:File = new File();
			
			file.addEventListener(Event.SELECT, flexSDKDirSelected, false, 0, true);
			file.browseForDirectory(_viewResourceConstants.INFO_SELECT_DIRECTORY);
		}
		
		protected function flexSDKDirSelected(event:Event):void {
			var selectedDir:File = File(event.target);
			var overlay:Boolean = flexVersion.selectedItem.overlay;
            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.errorString = _viewResourceConstants.ERROR_DIR_NOT_EMPTY;
    				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();
			}
		}
		
		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();
			}
			
		}
		
		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();
			}
			
			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 (debugMode)
                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();
		}
		
		protected function uncompressApacheFlexSDK():void {
			if (!_md5CompareUtil.fileIsVerified) {
				updateActivityStep(_viewResourceConstants.STEP_VERIFY_FLEX_SDK, StepItem.ERROR);
				
				log(_viewResourceConstants.ERROR_VERIFY_FLEX_SDK);
				
				abortInstallation();
				return;
			} else {
				updateActivityStep(_viewResourceConstants.STEP_VERIFY_FLEX_SDK, StepItem.COMPLETE);
				
				log(_viewResourceConstants.INFO_VERIFY_FLEX_SDK_DONE);
			}
			
			updateActivityStep(_viewResourceConstants.STEP_UNZIP_FLEX_SDK, StepItem.ACTIVE);
			
			try {
				log(_viewResourceConstants.INFO_UNZIPPING + _apacheFlexSDKCompressedFile.nativePath);
				
				if (_os.isWindows()) {
					unzip(_apacheFlexSDKCompressedFile, handleApacheFlexSDKZipFileUnzipComplete, handleApacheFlexSDKZipFileUnzipError);
				} else {
					untar(_apacheFlexSDKCompressedFile, _flexTempDir, handleApacheFlexSDKZipFileUnzipComplete, handleApacheFlexSDKZipFileUnzipError);
				}
			} catch (e:Error) {
				updateActivityStep(_viewResourceConstants.STEP_UNZIP_FLEX_SDK, StepItem.ERROR);
				abortInstallation();
			}
		}
		
		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();
		}
		
        protected function runInstallerScript():void
        {
            ant = new Ant();
            ant.output = output;
            Ant.usingDownloadCache = usingDownloadCache;
            Ant.downloadCacheFolder = downloadCacheFolder;
            
            var file:File;
            if (overlaying)
            {
                if (_os.isWindows())
                    file = _flexTempDir.resolvePath("installer.xml");
                else {
                    var directory:File = _flexTempDir.resolvePath(APACHE_FLEX_BIN_DISTRO_FILE_SHORT);
                    file = directory.resolvePath("installer.xml");
                }
            }
            else
                file = _flexHomeDir.resolvePath("installer.xml");
            addEventListener(Event.ENTER_FRAME, enterFrameHandler);
            var context:Object = { installer: true };
            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;
            context["air.sdk.url.path"] = airVersion.selectedItem.path;
            context["air.sdk.url.file"] = airVersion.selectedItem.file;
            context["flash.sdk.version"] = FLASH_PLAYER_VERSION;
            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 (!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 (debugMode)
                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 (currentStep > 0)
            {
                if (!Ant.currentAnt.project.status)
                    updateActivityStep(stepLabels[currentStep - 1], StepItem.ERROR);
                else if (currentStep == stepLabels.length)
                    updateActivityStep(stepLabels[currentStep - 1], StepItem.COMPLETE);
            }
            if (Ant.currentAnt.project.status)
                tracker.trackInstallerSuccess(APACHE_FLEX_BIN_DISTRO_VERSION_DISPLAY, APACHE_FLEX_BIN_DISTRO_VERSION, _os.os);
            cleanup(!Ant.currentAnt.project.status);
        }
        
        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;
            }
            log(s, -1, isPublic, skipLog);
        }
                
        private function enterFrameHandler(event:Event):void
        {
            ant.doCallback();
        }
                
		protected function downloadAIRRuntimeKitForWindows():void {
			updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK, StepItem.ACTIVE);
			
			try {
				log(_viewResourceConstants.INFO_DOWNLOADING_AIR_RUNTIME_KIT_WINDOWS + ADOBE_AIR_SDK_WIN_URL);
				_adobeAIRSDKZipFile = File.userDirectory.resolvePath(_flexTemp + File.separator + ADOBE_AIR_SDK_WIN_FILE);
				copyOrDownload(ADOBE_AIR_SDK_WIN_URL, handleAIRSDKDownload, _adobeAIRSDKZipFile, handleAIRSDKDownloadError);
			} catch (e:Error) {
				updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK, StepItem.ERROR);
				abortInstallation();
			}
		}
		
		protected function downloadAIRRuntimeKitForMac():void {
			updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK, StepItem.ACTIVE);
			
			try {
				log(_viewResourceConstants.INFO_DOWNLOADING_AIR_RUNTIME_KIT_MAC + ADOBE_AIR_SDK_MAC_URL);
				_adobeAIRSDKZipFile = File.userDirectory.resolvePath(_flexTemp + File.separator + ADOBE_AIR_SDK_MAC_FILE);
				copyOrDownload(ADOBE_AIR_SDK_MAC_URL, handleAIRSDKDownload, _adobeAIRSDKZipFile, handleAIRSDKDownloadError);
			} catch (e:Error) {
				updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK, StepItem.ERROR);
				abortInstallation();
			}
		}
		
		protected function downloadAIRRuntimeKitForLinux():void {
			updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK, StepItem.ACTIVE);
			
			try {
				log(_viewResourceConstants.INFO_DOWNLOADING_AIR_RUNTIME_KIT_MAC + ADOBE_AIR_SDK_LINUX_URL);
				_adobeAIRSDKZipFile = File.userDirectory.resolvePath(_flexTemp + File.separator + ADOBE_AIR_SDK_LINUX_FILE);
				copyOrDownload(ADOBE_AIR_SDK_LINUX_URL, handleAIRSDKDownload, _adobeAIRSDKZipFile, handleAIRSDKDownloadError);
			} catch (e:Error) {
				updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK, StepItem.ERROR);
				abortInstallation();
			}
		}
		
		protected function handleAIRSDKDownload(event:Event):void {
			try {
				writeFileToDirectory(_adobeAIRSDKZipFile, event.target.data);
			} catch (e:Error) {
				updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK, StepItem.ERROR);
				abortInstallation();
			}
			
			updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK, StepItem.COMPLETE);
			
			unzipAdobeAIRSDK();
		}
		
		protected function handleAIRSDKDownloadError(error:* = null):void {
			updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_ADOBE_AIR_SDK, StepItem.ERROR);
			log(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_AIR_SDK);
			abortInstallation();
		}
		
		protected function unzipAdobeAIRSDK():void {
			updateActivityStep(_viewResourceConstants.STEP_UNZIP_AIR_RUNTIME_KIT, StepItem.ACTIVE);
			
			try {
				if (_os.isWindows()) {
					unzipAdobeAIRSDKWindows()
				} else {
					unzipAdobeAIRSDKMac();
				}
			} catch (e:Error) {
				updateActivityStep(_viewResourceConstants.STEP_UNZIP_AIR_RUNTIME_KIT, StepItem.ERROR);
				abortInstallation();
			}
		}
		
		protected function unzipAdobeAIRSDKWindows():void {
			log(_viewResourceConstants.INFO_UNZIPPING + _adobeAIRSDKZipFile.nativePath);
			unzip(_adobeAIRSDKZipFile, handleAdobeAIRSDKWinZipFileUnzipComplete, handleAdobeAIRSDKWinZipFileUnzipError);
		}
		
		protected function unzipAdobeAIRSDKMac():void {
			if (NativeProcess.isSupported) {
				untar(_adobeAIRSDKZipFile, _flexHomeDir, handleAdobeAIRSDKMacUntarComplete, handleAdobeAIRSDKMacUntarError);
			} else {
				log(_viewResourceConstants.ERROR_NATIVE_PROCESS_NOT_SUPPORTED);
				updateActivityStep(_viewResourceConstants.STEP_UNZIP_AIR_RUNTIME_KIT, StepItem.ERROR);
			}
		}
		
		protected function handleAdobeAIRSDKMacUntarError(error:ProgressEvent = null):void {
			updateActivityStep(_viewResourceConstants.STEP_UNZIP_AIR_RUNTIME_KIT, StepItem.ERROR);
			abortInstallation();
		}
		
		protected function handleAdobeAIRSDKMacUntarComplete(event:Event):void {
			updateActivityStep(_viewResourceConstants.STEP_UNZIP_AIR_RUNTIME_KIT, StepItem.COMPLETE);
			log(_viewResourceConstants.INFO_FINISHED_UNTARING + _adobeAIRSDKZipFile.nativePath);
			downloadPlayerGlobalSWC();
		}
		
		protected function handleAdobeAIRSDKWinZipFileUnzipComplete(event:Event):void {
			updateActivityStep(_viewResourceConstants.STEP_UNZIP_AIR_RUNTIME_KIT, StepItem.COMPLETE);
			log(_viewResourceConstants.INFO_FINISHED_UNZIPPING + _adobeAIRSDKZipFile.nativePath);
			downloadPlayerGlobalSWC();
		}
		
		protected function handleAdobeAIRSDKWinZipFileUnzipError(error:ErrorEvent = null):void {
			updateActivityStep(_viewResourceConstants.STEP_UNZIP_AIR_RUNTIME_KIT, StepItem.ERROR);
		}
		
		protected function downloadPlayerGlobalSWC():void {
			updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_FLASH_PLAYER_GLOBAL_SWC, StepItem.ACTIVE);
			
			try {
				log(_viewResourceConstants.INFO_INSTALLING_PLAYERGLOBAL_SWC + ADOBE_FB_GLOBALPLAYER_SWC_URL);
				_fbGlobalPlayerDir = createFolder(_flexHome + File.separator + "frameworks" + File.separator + "libs" + File.separator + "player"
					+ File.separator + FLASH_PLAYER_VERSION);
				_fbGlobalPlayerFile = File.userDirectory.resolvePath(_fbGlobalPlayerDir.nativePath + File.separator + "playerglobal.swc");
				copyOrDownload(ADOBE_FB_GLOBALPLAYER_SWC_URL, handlePlayerGlobalDownload, _fbGlobalPlayerFile, handlePlayerGlobalDownloadError);
			} catch (e:Error) {
				updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_FLASH_PLAYER_GLOBAL_SWC, StepItem.ERROR);
				abortInstallation();
			}
		}
		
		protected function handlePlayerGlobalDownload(event:Event):void {
			try {
				var playerGlobalFile:File = File.userDirectory.resolvePath(_fbGlobalPlayerDir.nativePath + File.separator + "playerglobal.swc");
				writeFileToDirectory(playerGlobalFile, event.target.data);
			} catch (e:Error) {
				updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_FLASH_PLAYER_GLOBAL_SWC, StepItem.ERROR);
				abortInstallation();
			}
			updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_FLASH_PLAYER_GLOBAL_SWC, StepItem.COMPLETE);
			copyConfigFiles();
		}
		
		protected function handlePlayerGlobalDownloadError(event:ErrorEvent = null):void {
			updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_FLASH_PLAYER_GLOBAL_SWC, StepItem.ERROR);
			log(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_FLASH_PLAYER_SWC);
			abortInstallation();
		}
		
		protected function changeConfig(frameworksDir:File, file:File, flashPlayerVersion:String, swfVersion:String):void {
			if (isValidConfigFile(file)) {
				var configFile:FileStream = new FileStream();
				configFile.open(file, FileMode.READ);
				var contents:String = configFile.readMultiByte(configFile.bytesAvailable, "utf-8");
				var playerVersion:RegExp = /<target-player>\d\d\.\d<\/target-player>/;
				contents = contents.replace(playerVersion, "<target-player>" + flashPlayerVersion + "<\/target-player>");
				var playerSwfVersion:RegExp = /<swf-version>\d\d<\/swf-version>/;
				contents = contents.replace(playerSwfVersion, "<swf-version>" + swfVersion + "<\/swf-version>" );
				configFile.close();
				configFile.open(file,FileMode.WRITE);
				configFile.writeMultiByte(contents, "utf-8");					
				var copyToFile:File = frameworksDir.resolvePath(file.name);
				configFile.close();
				file.copyTo(copyToFile, true);
			}
		}
		
		protected function copyConfigFiles():void {
			var aborted:Boolean = false;
			
			updateActivityStep(_viewResourceConstants.STEP_INSTALL_CONFIG_FILES, StepItem.ACTIVE);
			
			try {
				//Config files
				var configFilesDir:File = File.userDirectory.resolvePath(_flexHome + File.separator + "ide" + File.separator + "flashbuilder" + File.separator
					+ "config");
				var configFiles:Array = configFilesDir.getDirectoryListing();
				var flexHomeFrameworksDir:File = File.userDirectory.resolvePath(_flexHome + File.separator + "frameworks");
				log(_viewResourceConstants.INFO_INSTALLING_CONFIG_FILES);
				
				for each (var file:File in configFiles) {
					changeConfig(flexHomeFrameworksDir, file, FLASH_PLAYER_VERSION, FLASH_PLAYER_SWF_VERSION);
				}
				
				file = File.userDirectory.resolvePath(_flexHome + File.separator + "flex-sdk-description.xml");
				var descriptionFile:FileStream = new FileStream();
				descriptionFile.open(file, FileMode.READ);
				var contents:String = descriptionFile.readMultiByte(descriptionFile.bytesAvailable, "utf-8");
				var description:RegExp = /<name>[^<]*<\/name>/;
				contents = contents.replace(description, "<name>Apache Flex " + APACHE_FLEX_BIN_DISTRO_VERSION + " FP " + FLASH_PLAYER_VERSION + " AIR " + AIR_VERSION + " en_US</name>");
				descriptionFile.close();
				descriptionFile.open(file,FileMode.WRITE);
				descriptionFile.writeMultiByte(contents, "utf-8");
				descriptionFile.close();
			} catch (e:Error) {
				updateActivityStep(_viewResourceConstants.STEP_INSTALL_CONFIG_FILES, StepItem.ERROR);
				log(_viewResourceConstants.ERROR_UNABLE_TO_INSTALL_CONFIG_FILES);
				abortInstallation();
				aborted = true;
			}
			
			if (!aborted) {
				updateActivityStep(_viewResourceConstants.STEP_INSTALL_CONFIG_FILES, StepItem.COMPLETE);
				downloadSwfObject();
			}
		}
		
		protected function downloadSwfObject():void {
			updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_SWFOBJECT, StepItem.ACTIVE);
			
			try {
				log(StringUtil.substitute(_viewResourceConstants.INFO_DOWNLOADING_FILE_FROM, [SWF_OBJECT_FILE, SWF_OBJECT_URL]));
				copyOrDownload(SWF_OBJECT_URL + SWF_OBJECT_FILE, handlSWFObjectDownload, null, handleSWFObjectDownloadError);
			} catch (e:Error) {
				updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_SWFOBJECT, StepItem.ERROR);
				abortInstallation();
			}
		}
		
		protected function handlSWFObjectDownload(event:Event):void {
			log(_viewResourceConstants.INFO_DOWNLOADED);
			var swfObjectZipFile:File = File.userDirectory.resolvePath(_flexTemp + File.separator + SWF_OBJECT_FILE);
			writeFileToDirectory(swfObjectZipFile, event.target.data);
			unzip(swfObjectZipFile, handleSWFObjectUnzipComplete, handleSWFObjectZipFileUnzipError);
		}
		
		protected function handleSWFObjectDownloadError(event:ErrorEvent = null):void {
			updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_SWFOBJECT, StepItem.ERROR);
			log(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_SWF_OBJECT);
			abortInstallation();
		}
		
		protected function handleSWFObjectUnzipComplete(event:Event):void {
			try {
				var expressInstallFile:File = File.userDirectory.resolvePath(_flexHome + File.separator + "swfobject" + File.separator + "expressInstall.swf");
				expressInstallFile.copyTo(_flexHomeDir.resolvePath("templates" + File.separator + "swfobject" + File.separator + "expressInstall.swf"));
				
				var swfObjectJSFile:File = File.userDirectory.resolvePath(_flexHome + File.separator + "swfobject" + File.separator + "swfobject.js");
				swfObjectJSFile.copyTo(_flexHomeDir.resolvePath("templates" + File.separator + "swfobject" + File.separator + "swfobject.js"));
				
				swfObjectJSFile.copyTo(_flexHomeDir.resolvePath("javascript" + File.separator + "FABridge" + File.separator + "samples" + File.separator
					+ "fabridge" + File.separator + "swfobject" + File.separator + "swfobject.js"));
				
				var swfObjectDir:File = _flexHomeDir.resolvePath("swfobject");
				swfObjectDir.deleteDirectory(true);
				
				updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_SWFOBJECT, StepItem.COMPLETE);
				installOSMF();
				
			} catch (e:Error) {
				updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_SWFOBJECT, StepItem.ERROR);
				log(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_SWF_OBJECT);
				abortInstallation();
			}
			
		}
		
		protected function handleSWFObjectZipFileUnzipError(event:Event):void {
			updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_SWFOBJECT, StepItem.ERROR);
			log(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_SWF_OBJECT);
			abortInstallation();
		}
		
		protected function installNextOptionalComponent():void {
			for each (var obj:InstallerComponentVO in _installerComponentsDataProvider) {
				if (obj.selected && !obj.installed && !obj.aborted) {
					switch (obj.label) {
						case _viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS:
						{
							installBlazeDS();
							return;
							break;
						}
						case _viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF:
						{
							installFontSwf();
							return;
							break;
						}
						default:
						{
							break;
						}
					}
				}
			}
			checkAndHandleAllOptionalComponentsInstalled();
		}
		
		protected function installBlazeDS():void {
			updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS, StepItem.ACTIVE);
			log(StringUtil.substitute(_viewResourceConstants.INFO_DOWNLOADING_FILE_FROM, [BLAZEDS_FILE, BLAZEDS_URL]));
			_blazeDSJarFile = File.userDirectory.resolvePath(_flexTemp + File.separator + BLAZEDS_FILE);
			copyOrDownload(BLAZEDS_URL + BLAZEDS_FILE, handleBlazeDSDownloadComplete, null, handleBlazeDSInstallError);
		}
		
		protected function handleBlazeDSDownloadComplete(event:Event):void {
			try {
				writeFileToDirectory(_blazeDSJarFile, event.target.data);
				copyFileToOptionalLibDir(_blazeDSJarFile);
				updateOptionalComponentInstallStatus(_viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS, true);
				updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS, false);
				updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS, StepItem.COMPLETE);
				clearData(URLLoader(event.target));
				installNextOptionalComponent();
			} catch (e:Error) {
				updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS, StepItem.ERROR);
				updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS, true);
				installNextOptionalComponent();
			}
		}
		
		protected function installFontSwf():void {
			updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, StepItem.ACTIVE);
			downloadFontSwfAFEFile();
		}
		
		protected function downloadFontSwfAFEFile():void {
			log(StringUtil.substitute(_viewResourceConstants.INFO_DOWNLOADING_FILE_FROM, [AFE_FILE, AFE_URL]));
			_afeJarFile = File.userDirectory.resolvePath(_flexTemp + File.separator + AFE_FILE);
			copyOrDownload(AFE_URL + AFE_FILE, handleFontSWFAFEFileDownloaded, null, handleFontSWFInstallError);
		}
		
		protected function handleFontSWFAFEFileDownloaded(event:Event):void {
			try {
				writeFileToDirectory(_afeJarFile, event.target.data);
				copyFileToOptionalLibDir(_afeJarFile);
				clearData(URLLoader(event.target));
				
				downloadFontSwfAGLFile();
				
			} catch (e:Error) {
				updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, StepItem.ERROR);
				updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, true);
				installNextOptionalComponent();
			}
		}
		
		protected function downloadFontSwfAGLFile():void {
			log(StringUtil.substitute(_viewResourceConstants.INFO_DOWNLOADING_FILE_FROM, [AGLJ40_FILE, AGLJ40_URL]));
			_aglj40JarFile = File.userDirectory.resolvePath(_flexTemp + File.separator + AGLJ40_FILE);
			copyOrDownload(AGLJ40_URL + AGLJ40_FILE, handleFontSWFAGLFileDownloaded, null, handleFontSWFInstallError);
		}
		
		protected function handleFontSWFAGLFileDownloaded(event:Event):void {
			try {
				writeFileToDirectory(_aglj40JarFile, event.target.data);
				copyFileToOptionalLibDir(_aglj40JarFile);
				clearData(URLLoader(event.target));
				
				downloadFontSwfFlexFontKitFile();
			} catch (e:Error) {
				updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, StepItem.ERROR);
				updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, true);
				installNextOptionalComponent();
			}
		}
		
		protected function downloadFontSwfFlexFontKitFile():void {
			log(StringUtil.substitute(_viewResourceConstants.INFO_DOWNLOADING_FILE_FROM, [FLEX_FONTKIT_FILE, FLEX_FONTKIT_URL]));
			_flexFontKitJarFile = File.userDirectory.resolvePath(_flexTemp + File.separator + FLEX_FONTKIT_FILE);
			copyOrDownload(FLEX_FONTKIT_URL + FLEX_FONTKIT_FILE, handleFontSWFFlexFontKitFileDownloaded, null, handleFontSWFInstallError);
		}
		
		protected function handleFontSWFFlexFontKitFileDownloaded(event:Event):void {
			try {
				writeFileToDirectory(_flexFontKitJarFile, event.target.data);
				copyFileToOptionalLibDir(_flexFontKitJarFile);
				clearData(URLLoader(event.target));
				
				downloadFontSwfRideauKitFile();
			} catch (e:Error) {
				updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, StepItem.ERROR);
				updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, true);
				installNextOptionalComponent();
			}
		}
		
		protected function downloadFontSwfRideauKitFile():void {
			log(StringUtil.substitute(_viewResourceConstants.INFO_DOWNLOADING_FILE_FROM, [RIDEAU_FILE, RIDEAU_URL]));
			_rideauJarFile = File.userDirectory.resolvePath(_flexTemp + File.separator + RIDEAU_FILE);
			copyOrDownload(RIDEAU_URL + RIDEAU_FILE, handleFontSWFRideauFileDownloaded, null, handleFontSWFInstallError);
		}
		
		protected function handleFontSWFRideauFileDownloaded(event:Event):void {
			try {
				writeFileToDirectory(_rideauJarFile, event.target.data);
				copyFileToOptionalLibDir(_rideauJarFile);
				clearData(URLLoader(event.target));
				
				updateOptionalComponentInstallStatus(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, true);
				updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, false);
				updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, StepItem.COMPLETE);
				installNextOptionalComponent();
			} catch (e:Error) {
				updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, StepItem.ERROR);
				updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, true);
				installNextOptionalComponent();
			}
		}
		
		protected function installOSMF():void {
			updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, StepItem.ACTIVE);
			downloadOSMFFile();
		}
		
		protected function downloadOSMFFile():void {
			_osmfSWFFile = File.userDirectory.resolvePath(_flexTemp + File.separator + OSMF_SWF_FILE.toLowerCase());
			
			log(StringUtil.substitute(_viewResourceConstants.INFO_DOWNLOADING_FILE_FROM, [OSMF_SWC_FILE, OSMF_SWC_URL]));
			_osmfSWCFile = File.userDirectory.resolvePath(_flexTemp + File.separator + OSMF_SWC_FILE.toLowerCase());
			if(_useOSMF2)
			{
				downloadOSMF2SWC();
			}
			else
			{
				copyOrDownload(OSMF_SWC_URL + OSMF_SWC_FILE,handleOSMFSWCFileDownloaded,null,handleOSMFSWCInstallError);
			}
		}
		
		protected function downloadOSMF2SWC():void
		{
            var url:String;
			var httpService:HTTPService = new HTTPService();
			httpService.resultFormat = HTTPService.RESULT_FORMAT_TEXT;
			url = httpService.url = Constants.SOURCEFORGE_DOWNLOAD_URL + OSMF_SWC_URL + OSMF_SWC_FILE;
            if (usingDownloadCache)
            {
                var cacheURL:String;
                if (url.indexOf("http") == 0)
                {
                    var c:int = url.indexOf("/");
                    c = url.indexOf("/", c + 1);
                    c = url.indexOf("/", c + 1);
                    // that should find the slash after the server.
                    cacheURL = url.substr(c + 1);
                    if (debugMode)
                        log("http caching.  url = " + cacheURL);                        
                }
                var cacheFile:File = File.applicationStorageDirectory.resolvePath(downloadCacheFolder);
                cacheFile = cacheFile.resolvePath(cacheURL);
                if (debugMode)
                    log("searching cache for " + cacheFile.url);                        
                if (cacheFile.exists)
                {
                    if (debugMode)
                        log("found file in cache");                        
                    url = cacheFile.url;
                    actuallyDownloadOSMF2SWC(new URLRequest(url));
                    return;
                }
            }
			httpService.addEventListener(ResultEvent.RESULT, getMirrorInfo);
			httpService.addEventListener(FaultEvent.FAULT, handleOSMFSWCUnzipError);
			httpService.send();
		}
		
		protected function getMirrorInfo(event:ResultEvent):void
		{
			var mirror:String = String(event.result);
			mirror = mirror.substr(mirror.indexOf('use_mirror=') + 'use_mirror='.length, mirror.length);
			mirror = mirror.substring(0, mirror.indexOf('">'));
			
			var mirrorURL:String = 'http://' + mirror + Constants.SOURCEFORGE_DL_URL + OSMF_SWC_URL + OSMF_SWC_FILE;
			var refererURL:String = Constants.SOURCEFORGE_DOWNLOAD_URL + OSMF_SWC_URL + '/download?use_mirror=' + mirror;
			
			var req:URLRequest = new URLRequest(mirrorURL);
			req.requestHeaders = [ new URLRequestHeader('Referer', refererURL) ];
			
            actuallyDownloadOSMF2SWC(req);
        }
        
        protected function actuallyDownloadOSMF2SWC(req:URLRequest):void
        {
			loader = new URLLoader();
			loader.dataFormat = URLLoaderDataFormat.BINARY;
            if (usingDownloadCache)
                loader.addEventListener(Event.COMPLETE, cacheOSMF2SWC);
			loader.addEventListener(Event.COMPLETE, handleOSMFSWCFileDownloaded);
			loader.addEventListener(ErrorEvent.ERROR, handleOSMFSWCInstallError);
			loader.addEventListener(IOErrorEvent.IO_ERROR, handleOSMFSWCInstallError);
			
			loader.load(req);
		}
		
        protected function cacheOSMF2SWC(event:Event):void {
            var url:String;
            url  = Constants.SOURCEFORGE_DOWNLOAD_URL + OSMF_SWC_URL + OSMF_SWC_FILE;
            var cacheURL:String;
            if (url.indexOf("http") == 0)
            {
                var c:int = url.indexOf("/");
                c = url.indexOf("/", c + 1);
                c = url.indexOf("/", c + 1);
                // that should find the slash after the server.
                cacheURL = url.substr(c + 1);
                if (debugMode)
                    log("http caching.  url = " + cacheURL);                        
            }
            if (cacheURL)
            {
                var cacheFile:File = File.applicationStorageDirectory.resolvePath(downloadCacheFolder);
                cacheFile = cacheFile.resolvePath(cacheURL);
                if (debugMode)
                    log("caching " + cacheFile.url);                        
                if (!cacheFile.exists)
                {
                    var fs:FileStream = new FileStream();
                    fs.open(cacheFile, FileMode.WRITE);
                    var srcData:ByteArray = ByteArray(loader.data);
                    srcData.position = 0;
                    var ba:ByteArray = new ByteArray();
                    srcData.readBytes(ba, 0, srcData.length);
                    ba.position = 0;
                    fs.writeBytes(ba, 0, ba.length);
                    fs.close();
                }
                else
                {
                    if (debugMode)
                        log("file was already in cache");                        
                }
            }
        }
        
		protected function handleOSMFSWCFileDownloaded(event:Event):void {
			try {
				writeFileToDirectory(_osmfSWCFile, event.target.data);
				copyFileToLibDir(_osmfSWCFile);
				unzip(_osmfSWCFile,handleOSMFSWCUnzipped,handleOSMFSWCUnzipError);
				clearData(URLLoader(event.target));
				
				updateOptionalComponentInstallStatus(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, true);
				updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, false);
				updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, StepItem.COMPLETE);
				installNextOptionalComponent();
			} catch (e:Error) {
				updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, StepItem.ERROR);
				updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, true);
				abortInstallation();
			}
		}
		
		/**
		 * Unzip osmf.swc, extract library.swf from it and copy it into frameworks/rsls/osmf_<flexversion>.<buildnumber>
		 * Delete other files extracted from osmf.swc
		 */
		protected function handleOSMFSWCUnzipped(event:Event):void
		{
			try {
				var osmfFileName:String =  "osmf_" + getFlexVersionBuildString() + ".swf";
				var copyToFile:File = _flexHomeDir.resolvePath("frameworks" + File.separator + "rsls" + File.separator + osmfFileName);
				var osmfLibrarySwfFile:File = _flexHomeDir.resolvePath("library.swf");
				osmfLibrarySwfFile.moveTo(copyToFile);
				var catalogXMLFile:File = _flexHomeDir.resolvePath("catalog.xml");
				if(catalogXMLFile.exists)
				{
					catalogXMLFile.deleteFile();
				}
				var manifestXMLFile:File = _flexHomeDir.resolvePath("manifest.xml");
				if(manifestXMLFile.exists)
				{
					manifestXMLFile.deleteFile();
				}
			}
			catch (e:Error) {
				updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, StepItem.ERROR);
				updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, true);
				abortInstallation();
			}
		}
		
		protected function handleOSMFSWCUnzipError(event:Event):void
		{
			updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, StepItem.ERROR);
			updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, true);
			abortInstallation();
		}
		
		protected function copyFileToOptionalLibDir(file:File):void {
			//Copy to "${FLEX_HOME}/lib/external/optional"
			var copyToFile:File = _flexHomeDir.resolvePath("lib" + File.separator + "external" + File.separator + "optional" + File.separator + file.name);
			file.copyTo(copyToFile, true);
		}
		
		protected function copyFileToLibDir(file:File):void {
			//Copy to "${FLEX_HOME}/frameworks/libs/"
			var copyToFile:File = _flexHomeDir.resolvePath("frameworks" + File.separator + "libs" + File.separator + file.name);
			file.copyTo(copyToFile, true);
		}
		
		protected function handleBlazeDSInstallError(event:* = null):void {
			updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS, StepItem.ERROR);
			updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_OPTIONAL_INSTALL_BLAZEDS, true);
			log(StringUtil.substitute(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_FILE, ["BlazeDS"]));
			installNextOptionalComponent();
		}
		
		protected function handleFontSWFInstallError(event:* = null):void {
			updateActivityStep(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, StepItem.ERROR);
			updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_OPTIONAL_INSTALL_FONTSWF, true);
			log(StringUtil.substitute(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_FILE, ["FontSwf Utility"]));
			installNextOptionalComponent();
		}
		
		protected function handleOSMFSWFInstallError(event:* = null):void {
			updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, StepItem.ERROR);
			updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, true);
			log(StringUtil.substitute(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_FILE, ["OSMF_SWF"]));
			installNextOptionalComponent();
		}
		
		protected function handleOSMFSWCInstallError(event:* = null):void {
			updateActivityStep(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, StepItem.ERROR);
			updateOptionalComponentInstallStatusAborted(_viewResourceConstants.STEP_REQUIRED_INSTALL_OSMF, true);
			log(StringUtil.substitute(_viewResourceConstants.ERROR_UNABLE_TO_DOWNLOAD_FILE, ["OSMF_SWC"]));
			installNextOptionalComponent();
		}
		
		protected function updateOptionalComponentInstallStatus(label:String, isInstalled:Boolean):void {
			for each (var obj:InstallerComponentVO in _installerComponentsDataProvider) {
				if (obj.label == label) {
					obj.installed = isInstalled;
				}
			}
		}
		
		protected function updateOptionalComponentInstallStatusAborted(label:String, isAborted:Boolean):void {
			for each (var obj:InstallerComponentVO in _installerComponentsDataProvider) {
				if (obj.label == label) {
					obj.aborted = isAborted;
				}
			}
		}
		
		protected function checkAndHandleAllOptionalComponentsInstalled():void {
			var allComponentsInstalled:Boolean = true;
			for each (var obj:InstallerComponentVO in _installerComponentsDataProvider) {
				if (!obj.required && obj.selected && !(obj.installed || obj.aborted)) {
					allComponentsInstalled = false;
				}
			}
			if (allComponentsInstalled) {
				tracker.trackInstallerSuccess(APACHE_FLEX_BIN_DISTRO_VERSION_DISPLAY, APACHE_FLEX_BIN_DISTRO_VERSION, _os.os);
				cleanup(false);
			}
		}
		
		protected function cleanup(isAbort:Boolean = false):void {
			try {
				_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);
			}
			else
			{
				log(_viewResourceConstants.INFO_INSTALLATION_COMPLETE);
				updateUIHandleInstallationComplete();
			}
		}
		
		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():void {
			browseBtn.enabled = false;
			installBtn.enabled = false;
			cleanup(true);
			log(_viewResourceConstants.INFO_ABORT_INSTALLATION);
			firstStepGroup.title = secondStepGroup.title = thirdStepGroup.title = _viewResourceConstants.INFO_ABORT_INSTALLATION;
		}
		
		protected function _langSelect_changeHandler(event:IndexChangeEvent):void {
			var defaultLanguage:String = ViewResourceConstants.DEFAULT_LANGUAGE;
			
			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 = [ _langSelect.selectedItem["data"], defaultLanguage ];
            resourceManager.update();
            setButtonWidths();			
		}
		
		override protected function resourcesChanged():void {
			super.resourcesChanged();
			
			if (_viewResourceConstants) {
				rememberInstallerComponents();
				updateWindowTitle();
				initiateInstallStepsActivity();
				initializeInstallerComponentsDataProvider();
				recallInstallerComponents();
			}
		}
		
		private var _selectedInstallerComponents:Vector.<InstallerComponentVO>;
		
		protected function rememberInstallerComponents():void {
			_selectedInstallerComponents = new Vector.<InstallerComponentVO>;
			for each(var item:InstallerComponentVO in _installerComponentsDataProvider) {
				if (item.selected) {
					_selectedInstallerComponents.push(item);
				}
			}
		}
		
		protected function recallInstallerComponents():void {
			for each(var item:InstallerComponentVO in _selectedInstallerComponents) {
				getInstallerComponentFromLabel(item.key).selected = true;
			}
		}
		
		protected function placeGroup(panel:Panel):void {
			panel.x = this.width / 2 - panel.width / 2;
		}
		
		protected function handleOptionalInstallsChange(event:IndexChangeEvent):void {
			var selectedItem:InstallerComponentVO = InstallerComponentVO(event.target.selectedItem);
			optionalInstallsTxtArea.text = selectedItem.message;
			/*			installChkBx.label = _viewResourceConstants.INSTALL_AGREE;
			if (selectedItem.answered) {
			if (selectedItem.selected) {
			installChkBx.selected = true;
			} else {
			installChkBx.selected = false;
			}
			} else {
			installChkBx.selected = false;
			}*/
			
			licenseLinkBtn.includeInLayout = true;
			_currentLicenseLabel = selectedItem.licenseName;
			_currentLicenseURL = selectedItem.licenseURL;
			checkIfAllRequiredComponentsPromptsAnswered();
			
		}
		
		protected function handleLicenceBtnClick(event:Event):void {
			navigateToURL(new URLRequest(_currentLicenseURL), "_blank");
		}
		
		protected function handleInstallPermissionChange(event:InstallItemSelectionEvent):void {
			if (installComponentsList.selectedItem != null) {
				installComponentsList.selectedItem.selected = (event.item.selected);
				installComponentsList.selectedItem.answered = true;
			} else {
				for (var i:int = 0; i < _installerComponentsDataProvider.length; i++) {
					_installerComponentsDataProvider.getItemAt(i).selected = event.item.selected;
					_installerComponentsDataProvider.getItemAt(i).answered = true;
				}
			}
			checkIfAllRequiredComponentsPromptsAnswered();
		}
		
		protected function checkIfAllRequiredComponentsPromptsAnswered():void {
			var success:Boolean = true;
			for each (var obj:InstallerComponentVO in _installerComponentsDataProvider) {
				if (obj.required && !obj.selected) {
					success = false;
				}
			}
			installBtn.enabled = success;
		}
		
		/************************ Utility methods *****************/
		
		private function createFolder(path:String):File {
			var dir:File = new File(path);
			
            if (!dir.exists)
    			dir.createDirectory();
			
			return dir;
		}
		
		private function copyOrDownload(url:String, handlerFunction:Function, dest:File = null, errorFunction:Function = null, nocache:Boolean = false):void {
			if (url.search("http") == 0) {
				download(url, handlerFunction, errorFunction, nocache);
			} else if (url.search("file://") == 0) {
				download(url, handlerFunction, errorFunction, nocache);
			} else {
				var source:File = new File(url);
				
				try {
					source.copyTo(dest, true);
				} catch (error:Error) {
					if (errorFunction != null) {
						errorFunction.call(null);
					}
					log(_viewResourceConstants.ERROR_UNABLE_TO_COPY_FILE + error.errorID + " " + error.message);
				}
			}
		}
		
		private function download(url:String, handlerFunction:Function, errorFunction:Function = null, nocache:Boolean = false):void {
			loader = new URLLoader();
            if (debugMode)
            {
                log("downloading " + url);
                if (usingDownloadCache)
                    log("using download cache");
                if (nocache)
                    log("not caching this download");
            }                
            if (usingDownloadCache && !nocache)
            {
                var cacheURL:String
                if (_useMirror && url.indexOf(useMirrorPath(_mirrorURLUtil.mirrorURL)) != -1)
                {
                    cacheURL = url.substr(useMirrorPath(_mirrorURLUtil.mirrorURL).length);
                    if (debugMode)
                        log("mirror caching.  url = " + cacheURL);                        
                }
                else
                {
                    if (url.indexOf("http") == 0)
                    {
                        var c:int = url.indexOf("/");
                        c = url.indexOf("/", c + 1);
                        c = url.indexOf("/", c + 1);
                        // that should find the slash after the server.
                        cacheURL = url.substr(c + 1);
                        if (debugMode)
                            log("http caching.  url = " + cacheURL);                        
                    }
                }
                if (cacheURL)
                {
                   var cacheFile:File = File.applicationStorageDirectory.resolvePath(downloadCacheFolder);
                   cacheFile = cacheFile.resolvePath(cacheURL);
                   if (debugMode)
                       log("searching cache for " + cacheFile.url);                        
                   if (cacheFile.exists)
                   {
                       if (debugMode)
                           log("found file in cache");                        
                       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(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 (debugMode)
                    log("download progress " + event.bytesLoaded + "  " + event.bytesTotal, -1, false);
    			
    			progressBar.percent = percentLoaded;
            }
		}
		
		private function handleDownloadComplete(event:Event):void {
			_previousDisplayedPercent = 0;
			clearData(URLLoader(event.target));
		}
		
		private function clearData(v:URLLoader):void {
			ByteArray(v.data).clear();
			System.gc();
		}
		
		private function unzip(fileToUnzip:File, unzipCompleteFunction:Function, unzipErrorFunction:Function = null):void {
			var zipFileBytes:ByteArray = new ByteArray();
			var fs:FileStream = new FileStream();
			var fzip:Zip = new Zip();
			
			fs.open(fileToUnzip, FileMode.READ);
			fs.readBytes(zipFileBytes);
			fs.close();
			
			fzip.addEventListener(ZipEvent.FILE_LOADED, onFileLoaded, false, 0, true);
			fzip.addEventListener(Event.COMPLETE, unzipCompleteFunction, false, 0, true);
			fzip.addEventListener(Event.COMPLETE, onUnzipComplete, false, 0, true);
			if (unzipErrorFunction != null) {
				fzip.addEventListener(ErrorEvent.ERROR, unzipErrorFunction, false, 0, true);
				_fileUnzipErrorFunction = unzipErrorFunction
			}
			fzip.loadBytes(zipFileBytes);
		}
		
		private function onFileLoaded(e:ZipEvent):void {
			try {
				var fzf:ZipFile = e.file;
				var f:File;
                if (overlaying)
                    f = _flexTempDir.resolvePath(fzf.filename);
                else
                    f = _flexHomeDir.resolvePath(fzf.filename);
				var fs:FileStream = new FileStream();
				
				if (isDirectory(fzf)) {
					// Is a directory, not a file. Dont try to write anything into it.
					return;
				}
				
				fs.open(f, FileMode.WRITE);
				fs.writeBytes(fzf.content);
				fs.close();
				
			} catch (error:Error) {
				_fileUnzipErrorFunction.call();
			}
		}
		
		private function isDirectory(f:ZipFile):Boolean {
			if (f.filename.substr(f.filename.length - 1) == "/" || f.filename.substr(f.filename.length - 1) == "\\") {
				return true;
			}
			return false;
		}
		
		private function onUnzipComplete(event:Event):void {
			var fzip:Zip = event.target as Zip;
			fzip.close();
			fzip.removeEventListener(ZipEvent.FILE_LOADED, onFileLoaded);
			fzip.removeEventListener(Event.COMPLETE, onUnzipComplete);
		}
		
		private function untar(source:File, destination:File, unTarCompleteFunction:Function, unTarErrorFunction:Function):void {
			var tar:File;
			var startupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo();
			var arguments:Vector.<String> = new Vector.<String>();
			
			if (_os.isLinux()) {
				tar = new File("/bin/tar");
			}
			else {
				tar = new File("/usr/bin/tar");	
			}
			
			arguments.push("xf");
			arguments.push(source.nativePath);
			arguments.push("-C");
			arguments.push(destination.nativePath);
			
			startupInfo.executable = tar;
			startupInfo.arguments = arguments;
			
			_process = new NativeProcess();
			_process.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, unTarFileProgress, false, 0, true);
			_process.addEventListener(ProgressEvent.STANDARD_ERROR_DATA, unTarErrorFunction, false, 0, true);
			_process.addEventListener(ProgressEvent.STANDARD_ERROR_DATA, unTarError, false, 0, true);
			_process.addEventListener(NativeProcessExitEvent.EXIT, unTarCompleteFunction, false, 0, true);
			_process.addEventListener(NativeProcessExitEvent.EXIT, unTarComplete, false, 0, true);
			_process.start(startupInfo);
		}
		
		private function unTarError(event:Event):void {
			var output:String = _process.standardError.readUTFBytes(_process.standardError.bytesAvailable);
			
			log(_viewResourceConstants.ERROR_NATIVE_PROCESS_ERROR);
			log(output);
		}
		
		private function unTarFileProgress(event:Event):void {
			var output:String = _process.standardOutput.readUTFBytes(_process.standardOutput.bytesAvailable);
			
			log(output);
		}
		
		private function unTarComplete(event:NativeProcessExitEvent):void {
			_process.closeInput();
			_process.exit(true);
		}
		
		private function writeFileToDirectory(file:File, data:ByteArray):void {
			var fs:FileStream = new FileStream();
			fs.open(file, FileMode.WRITE);
			fs.writeBytes(data);
			fs.close();
		}
		
		private function isValidConfigFile(file:File):Boolean {
			var name:String = file.name;
			
			if (name.search("-config.xml") == -1) {
				return false;
			} else {
				return true;
			}
		}
		
		private function isAirConfigFile(file:File):Boolean {
			var name:String = file.name;
			
			if (name.search("air") == 0) {
				return true;
			} else {
				return false;
			}
		}
		
		private function log(text:String, position:int = -1, isPublic:Boolean = true, skipLog:Boolean = false):void {
			if (position == -1) {
                if (!skipLog)
    				_messages.addItem(text);
                if (isPublic)
                    lastPublicMessage = text;
			} else {
				_messages.addItemAt(text, position);
			}
            if (debugMode)
                trace(text);
		}
		
		private function showConsole(event:Event):void {
			var console:ConsoleWindow = new ConsoleWindow();
			
			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 {
			// TODO only enable close button when finished or when an error occurs
			// TODO anything we need to clean up?
			cleanup();
			close();
		}
		
		protected function clickLogo(event:MouseEvent):void {
			navigateToURL(new URLRequest(Constants.APACHE_FLEX_URL));
		}
		
		protected function getStepItemFromStepLabel(stepLabel:String):StepItem {
			for each (var s:StepItem in _installationSteps) {
				if (s.label == stepLabel) {
					return s;
				}
			}
			
			return null;
		}
		
		protected function getInstallerComponentFromLabel(key:String):InstallerComponentVO {
			for each (var s:InstallerComponentVO in _installerComponentsDataProvider) {
				if (s.key == key) {
					return s;
				}
			}
			
			return null;
		}
		
		protected function updateActivityStep(stepLabel:String, status:String):void {
			var step:StepItem = getStepItemFromStepLabel(stepLabel);
			
			if (step) {
				step.status = status;
			}
		}
		
		private function isDirectoryEmpty(dir:File):Boolean {
			var result:Boolean;
			
			var filesArray:Array = dir.getDirectoryListing();
			
			var length:int = filesArray.length;
			result = length == 0;
			if (length == 1) {
				var explodedPath:Array = File(filesArray[0]).url.split("/");
				
				// the .DS_Store file doesn't bother anybody, so we can safely ignore it.
                // also ignore local.properties so you an override install settings
				result = explodedPath[explodedPath.length - 1] == ".DS_Store" ||
                    explodedPath[explodedPath.length - 1] == "local.properties";
			}
			
			return result;
		}
		
		protected function showDisclaimer():void {
			var request:URLRequest = new URLRequest(Constants.APACHE_FLEX_URL + Constants.DISCLAIMER_PATH);
			
			navigateToURL(request, "_blank");
		}
		
		protected function installComponentsList_creationCompleteHandler(event:FlexEvent):void {
			installComponentsList.addEventListener(InstallItemSelectionEvent.INSTALL_ITEM_SELECTION_CHANGED, handleInstallPermissionChange);
		}
		
		private function onMouseRoll(event:MouseEvent):void {
			if (event.type == MouseEvent.MOUSE_OVER) {
				event.target.styleName = "linkTextHover";
			} else {
				event.target.styleName = "linkText";
			}
		}
		
		private function getFlexVersionBuildString():String
		{
			var flexPropertiesFile:File = _flexHomeDir.resolvePath("flex-sdk-description.xml");
			var fs:FileStream = new FileStream();
			fs.open(flexPropertiesFile, FileMode.READ);
			var contents:XML = new XML(fs.readMultiByte(fs.bytesAvailable, "utf-8"));
			fs.close();
			return contents.version + "." + contents.build;
		}
	]]></fx:Script>
	
	<fx:Declarations>
		<s:Sine id="ease"/>
		<s:BlurFilter id="blur"/>
	</fx:Declarations>
	
	<s:states>
		<s:State name="default"/>
		<s:State name="directoryState"/>
		<s:State name="optionsState"/>
		<s:State name="installState"/>
	</s:states>
	
	<s:transitions>
		<s:Transition id="showDefault" fromState="*" toState="default">
			<s:Sequence id="t0" targets="{[zeroStepGroup]}" effectEnd="placeGroup(zeroStepGroup)">
				<s:SetAction target="{zeroStepGroup}" property="visible" value="true"/>
				<s:SetAction target="{firstStepGroup}" property="visible" value="false"/>
				<s:SetAction target="{secondStepGroup}" property="visible" value="false"/>
				<s:SetAction target="{thirdStepGroup}" property="visible" value="false"/>
				<s:Move target="{zeroStepGroup}" xFrom="800" xTo="{this.width/2 - zeroStepGroup.width/2}" duration="500" easer="{ease}"/>
			</s:Sequence>
		</s:Transition>
		<s:Transition id="showDirectory" fromState="*" toState="directoryState">
			<s:Sequence id="t1" targets="{[firstStepGroup]}" effectEnd="placeGroup(firstStepGroup)">
				<s:SetAction target="{zeroStepGroup}" property="visible" value="false"/>
				<s:SetAction target="{firstStepGroup}" property="visible" value="true"/>
				<s:SetAction target="{secondStepGroup}" property="visible" value="false"/>
				<s:SetAction target="{thirdStepGroup}" property="visible" value="false"/>
				<s:Move target="{firstStepGroup}" xFrom="800" xTo="{this.width/2 - firstStepGroup.width/2}" duration="500" easer="{ease}"/>
			</s:Sequence>
		</s:Transition>
		<s:Transition id="showOptions" fromState="*" toState="optionsState">
			<s:Sequence id="t2" targets="{[secondStepGroup]}" effectEnd="placeGroup(secondStepGroup)">
				<s:SetAction target="{zeroStepGroup}" property="visible" value="false"/>
				<s:SetAction target="{firstStepGroup}" property="visible" value="false"/>
				<s:SetAction target="{secondStepGroup}" property="visible" value="true"/>
				<s:SetAction target="{thirdStepGroup}" property="visible" value="false"/>
				<s:Move target="{secondStepGroup}" xFrom="800" xTo="{this.width/2 - secondStepGroup.width/2}" duration="500" easer="{ease}"/>
			</s:Sequence>
		</s:Transition>
		<s:Transition id="showInstall" fromState="*" toState="installState">
			<s:Sequence id="t3" targets="{[thirdStepGroup]}" effectEnd="placeGroup(thirdStepGroup)">
				<s:SetAction target="{zeroStepGroup}" property="visible" value="false"/>
				<s:SetAction target="{firstStepGroup}" property="visible" value="false"/>
				<s:SetAction target="{secondStepGroup}" property="visible" value="false"/>
				<s:SetAction target="{thirdStepGroup}" property="visible" value="true"/>
				<s:Move target="{thirdStepGroup}" xFrom="800" xTo="{this.width/2 - thirdStepGroup.width/2}" duration="500" easer="{ease}"/>
			</s:Sequence>
		</s:Transition>
	</s: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"
						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}"
					  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: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: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%"
					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%"
				 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>
