package fl.display {

	import fl.events.ProLoaderRSLPreloaderSandboxEvent;
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.events.EventDispatcher;
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.display.Sprite;
	import flash.net.URLRequest;
	import flash.system.LoaderContext;
	import flash.utils.ByteArray;
	import flash.utils.getQualifiedClassName;

	/**
	 * The ProLoader class loads SWF files or images. Use fl.display.ProLoader instead
	 * of flash.display.Loader when loading SWF files generated by Flash Professional.
	 * ProLoader class members mirror Loader class members. Instead of
	 * a LoaderInfo object, ProLoader uses a ProLoaderInfo object. ProLoaderInfo class members 
	 * mirror LoaderInfo class members.
	 * 
	 * <p><b>Note</b> ProLoader is not a subclass of flash.display.Loader. To use ProLoader, you are required
	 * to change all Loader type references to ProLoader.</p>
	 *
	 * <p>ProLoader delivers a consistent loading experience. It is especially helpful with 
	 * SWF files that use RSL preloading. For example, SWF files that use TLF text use RSL 
	 * preloading by default. In these cases, ProLoaderInfo delays sending the INIT or COMPLETE 
	 * events until RSL preloading has completed and real content is available. As a result, 
	 * the <code>content</code> property can then access real content. ProLoader also
	 * helps you avoid other problems, such as:</p>
	 *
	 * <ul>
	 * <li>Extra <code>addedToStage</code> and <code>removedFromStage</code> events</li> 
	 * <li>Content that is loaded to the wrong parent on frame one (applies to content published to Flash 
	 * Player 10.2 or higher using Flash Professional CS5.5 or higher).</li></ul>
	 * 
	 * <p><b>Warning</b> Certain ProLoader members do not support all runtime versions. 
	 * Access these members only when your published AIR or Flash Player version 
	 * supports them. Otherwise, these APIs throw runtime errors. 	 
	 * Members with limited runtime support include the following methods and property:</p>
	 * <ul>
	 * <li><code>unloadAndStop()</code></li>
	 * <li><code>loadFilePromise()</code></li> 
	 * <li><code>uncaughtErrorEvents</code></li>
	 * </ul>
	 * <p>See the reference topic for each API to 
	 * verify its runtime support.</p>
	 * 
	 * @playerversion AIR 1.0
	 * @playerversion Flash 9
	 * @productversion Flash CS5.5
	 * @langversion 3.0
	 *
	 */

	public class ProLoader extends Sprite {
		private var _cli:ProLoaderInfo;
		private var _loader:Loader;
		private var _realContentLoader:Loader;
		private var _loading:Boolean;
		private var _hasRequestedContentParentProp:Boolean;

	     /**
	     * Creates a ProLoader object that you can use to load files, such as SWF, JPEG, GIF, or PNG files.
	     * Call the <code>load()</code> method to load the asset as a child of the ProLoader instance. 
	     * You can then add the ProLoader object to the display list (for instance, by using the 
	     * <code>addChild()</code> method of a DisplayObjectContainer instance).  
	     * The asset appears on the stage as it loads.
	     * 
	     * <p>You can also use a ProLoader instance "offlist," that is without adding it to a display object
	     * container on the display list. In this mode, the Loader instance might be used to load a SWF file 
	     * that contains additional modules of an application. </p>
	     * 
	     * <p>To detect when the SWF file is finished loading, you can use the events of the ProLoaderInfo  
	     * object associated with the <code>contentLoaderInfo</code> property of the ProLoader object.
	     * At that point, the code in the module SWF file can be executed to initialize and start the module.
	     * In the offlist mode, a ProLoader instance might also be used to load a SWF file that contains components or 
	     * media assets. Again, you can use the ProLoaderInfo object event notifications to detect when the 
	     * components are finished loading. At that point, the application can start using the components 
	     * and media assets in the library of the SWF file by instantiating the ActionScript 3.0 classes that represent 
	     * those components and assets.</p>
	     * 
	     * <p>To determine the status of a ProLoader object, monitor the following events that the ProLoaderInfo  
	     * object associated with the <code>contentLoaderInfo</code> property of the ProLoader object:</p>
	     * 
	     * <ul>
	     *   
	     * <li>The <code>open</code> event is dispatched when loading begins.</li>
	     *   
	     * <li>The <code>ioError</code> or <code>securityError</code> event is dispatched if the file 
	     * cannot be loaded or if an error occured during the load process. </li>
	     *   
	     * <li>The <code>progress</code> event fires continuously while the file is being loaded.</li>
	     *   
	     * <li>The <code>complete</code> event is dispatched when a file completes downloading, but before
	     * the loaded movie clip's methods and properties are available. If the loaded SWF file uses RSL preloading,
	     * this event is dispatched after RSL preloading completes. At this point, real content is available in the 
	     * <code>content</code> property.</li>
	     *   
	     * <li>The <code>init</code> event is dispatched after the properties and methods of the loaded SWF file
	     * are accessible, so you can begin manipulating the loaded SWF file. 
	     * This event is dispatched before the <code>complete</code> handler. In streaming SWF files, 
	     * the <code>init</code> event can occur significantly earlier than the <code>complete</code> event. 
	     * For most purposes, use the <code>init</code> handler. If the loaded SWF file uses RSL preloading,
	     * this event is dispatched after RSL preloading completes. At this point, real content is available in the 
	     * <code>content</code> property.</li>
	     * 
	     * </ul>
	     *
	     * 
	     * @productversion Flash CS5.5
	     * @playerversion AIR 1.0
	     * @playerversion Flash 9
	     * @langversion 3.0
	     *
	     * @see fl.display.ProLoader#load() 
	     * @see fl.display.ProLoaderInfo
	     * 
	     * @internal Need wording on parent/child relationships, root DisplayObjects, and so on.
	     *  
	     */
     	public function ProLoader()
		{
			_loader = new Loader();
			_loader.contentLoaderInfo.sharedEvents.addEventListener(ProLoaderRSLPreloaderSandboxEvent.PROLOADER_RSLPRELOADER_SANDBOX, handleProLoaderRSLPreloaderSandboxEvent, false, 0, true);
			super.addChild(_loader);
			_realContentLoader = null;
			_cli = new ProLoaderInfo(this);
			_loading = false;
			_hasRequestedContentParentProp = false;
		}

		/**
		 * @private
		 */
		private function handleProLoaderRSLPreloaderSandboxEvent(e:Object):void
		{
			if (e.loaderInfo != null) {
				try {
					_realContentLoader = e.loaderInfo.loader;
				} catch (se:SecurityError) {
					_realContentLoader = null;
				}
				_cli.realContentLoaderInfo = e.loaderInfo;
			} else if (e.shape != null && getQualifiedClassName(e.shape) == "flash.display::Shape") {
				// for security, we must ensure we are getting a shape and not a subclass
				// so we are not getting tricked into calling some overridden evil get parent
				try {
					// gives one last chance to straightent out the parent situation
					// might work if allowaccess was called on frame one. Get parent of
					// shape to ensure we have sandbox access to the content before
					var content:DisplayObjectContainer = e.shape.parent;
					if (content != null) {
						content.removeChild(e.shape);
						if (super.numChildren < 2) {
							super.addChild(content);
						}
					}
				} catch (se:SecurityError) {
				}
			}
		}

		/**
		 * @private
		 */
		function loadDoneCallback(d:DisplayObject):Boolean
		{
			// called by ProLoaderInfo when the content is ready and before the events
			// are dispatched. Returns false if load was cancelled
			if (!_loading) {
				_loader.unload();
				return false;
			}
			_loading = false;
			if (d != null) {
				try {
					// this incredibly complex logic is trying to deal with all the cases of
					// whether we are running as a swf 11, whether the loaded content has the
					// new or old RSLPreloader logic, etc.
					if (_cli.realContentLoaderInfo == null) {
						// if we get in here we either have no RSLPreloader or it has old logic
						if (d.loaderInfo.loader != _loader) {
							// this means we have an RSLPreloader with old logic
							_realContentLoader = d.loaderInfo.loader;
							_cli.realContentLoaderInfo = _realContentLoader.contentLoaderInfo;
							if (_hasRequestedContentParentProp) {
								var p:DisplayObjectContainer = _loader.content.parent as DisplayObjectContainer;
								if (p == this || p == null) {
									while (super.numChildren > 1) super.removeChildAt(1);
									super.addChild(d);
								} else {
									p.addChildAt(d, p.getChildIndex(_loader.content));
									p.removeChild(_loader.content);
								}
							} else {
								super.addChild(d);
							}
						} else if (!_hasRequestedContentParentProp || (_cli._lcRequestedContentParentSet && d.parent != this)) {
							// this means we have content with no RSL preload, but no LoaderContext.parent functionality
							// OR we were not able to reparent because of sandbox concerns, but try again in case
							// allowDomain() was called on frame one of loaded content.
							super.addChild(d);
						}
					} else if (_hasRequestedContentParentProp) {
						// this means we have a new RSLPreloader and LoaderContext.parent functionality
						if (d.parent == this) {
							// if the parent is the ProLoader, RSLPreloader will have tried
							// to call removeChild but had an error
							while (super.numChildren > 2) super.removeChildAt(1);
						}
					} else {
						// this means we have a new RSLPreloader and no LoaderContext.parent functionality
						super.addChild(d);
					}
				} catch (se:SecurityError) {
				}
			}
			return true;
		}

		/**
		 * get access to the flash.display.Loader being used by the ProLoader to do all the work.
		 * @private
		 */
		public function get realLoader():Loader
		{
			// get this way to ensure sandbox security checks are made
			return _loader.contentLoaderInfo.loader;
		}

		/**
		 * get access to the flash.display.Loader that did the loadBytes on the true content in
		 * the case of loading a flash pro RSL preloading swf
		 * @private
		 */
		public function get realContentLoader():Loader
		{
			// get this way to ensure sandbox security checks are made
			return (_realContentLoader == null) ? null : _realContentLoader.contentLoaderInfo.loader;
		}

		/**
         	 * Contains the root display object of the SWF file or image (JPG, PNG, or GIF) 
         	 * file that was loaded by using the <code>load()</code> or <code>loadBytes()</code> methods.
	         *
	         * @throws SecurityError The loaded SWF file or image file belongs to a security 
	         * sandbox to which you do not have access. For a loaded SWF file, you can avoid this situation by having
	         * the file call the <code>Security.allowDomain()</code> method or by having the loading file specify a
	         * <code>loaderContext</code> parameter with its <code>securityDomain</code> property set to 
	         * <code>SecurityDomain.currentDomain</code> when you call the <code>load()</code>  or 
	         * <code>loadBytes()</code> method.
      		 *
		 * @playerversion AIR 1.0
		 * @playerversion Flash 9
		 * @productversion Flash CS5.5
		 * @langversion 3.0
		 *		 
		 */
		public function get content():DisplayObject
		{
			if (super.numChildren > 1) return super.getChildAt(1);
			if (_realContentLoader) return _realContentLoader.content;
			return _loader.content;
		}

		/**
	    	 * Returns a ProLoaderInfo object corresponding to the object being loaded. ProLoaderInfo objects 
     		 * are shared between the ProLoader object and the loaded content object. The ProLoaderInfo object 
     		 * supplies loading progress information and statistics about the loaded file. 
     		 * 
     		 * <p>Events related to the load are dispatched by the ProLoaderInfo object referenced by the 
     		 * <code>contentLoaderInfo</code> property of the ProLoader object. The <code>contentLoaderInfo</code> 
     		 * property is set to a valid ProLoaderInfo object, even before the content is loaded, so that you can add 
     		 * event listeners to the object prior to the load.</p>
		 * 
		 * <p>To detect uncaught errors that happen in a loaded SWF, use the 
		 * <code>ProLoader.uncaughtErrorEvents</code> property, not the 
		 * <code>ProLoader.contentLoaderInfo.uncaughtErrorEvents</code> property.</p>
		 *
		 * <p><bold>Note</bold> The contentLoaderInfo property returns a ProLoaderInfo object.
		 * ProLoaderInfo is not a subclass of LoaderInfo and hence does not give you the advantage
		 * of an implicit cast to the super-class. Therefore, be sure to change your type declarations from 
		 * LoaderInfo to ProLoaderInfo.</p>

     		 * 
		 * @playerversion AIR 1.0
		 * @playerversion Flash 9
		 * @productversion Flash CS5.5
		 * @langversion 3.0
		 *
		 */
		public function get contentLoaderInfo():ProLoaderInfo {
			return _cli;
		}

		/**
     		 * Cancels a <code>load()</code> method operation that is currently in progress for the ProLoader instance.
		 *
		 * @playerversion AIR 1.0
		 * @playerversion Flash Player 9
		 * @productversion Flash CS5.5
		 * @langversion 3.0
		 *
		 */
		public function close():void {
			if (_loading) {
				_loading = false;
				// we may be still acting as though the load is incomplete to allow RSL preloading
				// to finish, so catch any errors
				try { _loader.close(); } catch (err:Error) { }
			} else {
				_loader.close();
			}
		}

		/**
	         * Loads a SWF, JPEG, progressive JPEG, unanimated GIF, or PNG file into an object that is a child of 
	         * this ProLoader object. If you load an animated GIF file, only the first frame is displayed.
	         * As the ProLoader object can contain only a single child, issuing a subsequent <code>load()</code> 
	         * request terminates the previous request, if still pending, and commences a new load.
	         *
	         * <p><b>Note</b>: 
	         * In  AIR 1.5 and Flash Player 10, the maximum size for a loaded image is 8,191 pixels in width or height, 
	         * and the total number of pixels cannot exceed 16,777,215 pixels. (So, if an loaded image is 8,191 pixels 
	         * wide, it can only be 2,048 pixels high.) In Flash Player 9 and earlier and AIR 1.1 and earlier, the limitation
	         * is 2,880 pixels in height and 2,880 pixels in width.</p>
	         * 
	         * <p>A SWF file or image loaded into a ProLoader object inherits the position, rotation, and scale 
	         * properties of the parent display objects of the ProLoader object. </p>
	         * 
	         * <p>Use the <code>unload()</code> method to remove movies or images loaded with this 
	         * method, or to cancel a load operation that is in progress.</p>
	         *
	         * <p>You can prevent a SWF file from using this method by setting the  <code>allowNetworking</code> 
	         * parameter of the the <code>object</code> and <code>embed</code> tags in the HTML 
	         * page that contains the SWF content.</p>
	         * 
	         * <p>When you use this method, consider the Flash Player security model,
	         *  which is described in the ProLoader class description. </p>
	         * 
	         * <p> In Flash Player 10 and later, if you use a multipart Content-Type (for example "multipart/form-data") 
	         * that contains an upload (indicated by a "filename" parameter in a "content-disposition" header within the POST body),
	         * the POST operation is subject to the security rules applied to uploads:</p>
	         * <ul>
	         * <li>The POST operation must be performed in response to a user-initiated action, such as a mouse click or key press.</li>
	         * <li>If the POST operation is cross-domain (the POST target is not on the same server as the SWF file 
	         * that is sending the POST request),
	         * the target server must provide a URL policy file that permits cross-domain access.</li>
	         * </ul>
	         * <p>Also, for any multipart Content-Type, the syntax must be valid (according to the RFC2046 standard).
	         * If the syntax appears to be invalid, the POST operation is subject to the security rules applied to uploads.</p>
	         *
	         * <p>For more information related to security, see the Flash Player Developer Center Topic: 
	         * <a href="http://www.adobe.com/go/devnet_security_en" target="external">Security</a>.</p>
	         *
	         * @param request  The absolute or relative URL of the SWF, JPEG, GIF, or PNG file to be loaded. A 
	         * relative path must be relative to the main SWF file. Absolute URLs must include the 
	         * protocol reference, such as http:// or file:///. Filenames cannot include disk drive 
	         * specifications.
	         * 
	         * @param context A LoaderContext object, which has properties that define the following:
	         * 
	         * <ul>
	         * 
	         * <li>Whether or not to check for the existence of a policy file 
	         * upon loading the object</li>
	         * 
	         * <li>The ApplicationDomain for the loaded object</li>
	         * 
	         * <li>The SecurityDomain for the loaded object</li>
	         *
	         * <li>The ImageDecodingPolicy for the loaded image object</li>
	         * 
	         * </ul>
	         * <p>If the <code>context</code> parameter is not specified or refers to a null object,
	         * the loaded content remains in its own security domain.</p>
	         * 
	         * <p>For complete details, see the description of the properties in the 
	         * <a href="../../flash/system/LoaderContext.html">LoaderContext</a> class.</p>
	         *
	         * @throws IOError The <code>digest</code> property of the <code>request</code> object is not 
	         * <code>null</code>. You should only set the <code>digest</code> property of a URLRequest object
	         * when calling the <code>URLLoader.load()</code> method when loading a SWZ file (an Adobe 
	         * platform component).
	         *
	         * @throws SecurityError The value of <code>LoaderContext.securityDomain</code> must be either <code>null</code>
	         * or <code>SecurityDomain.currentDomain</code>.  This reflects the fact that you can only
	         * place the loaded media in its natural security sandbox or your own (the latter requires a
	         * policy file).
	         *
	         * @throws SecurityError Local SWF files may not set LoaderContext.securityDomain to anything
	         * other than <code>null</code>.  It is not permitted to import non-local media into a local
	         * sandbox, or to place other local media in anything other than its natural sandbox.
	         *
	         *  @throws SecurityError  You cannot connect to commonly reserved ports. 
	         * For a complete list of blocked ports, see "Restricting Networking APIs" in the 
	         * <em>ActionScript 3.0 Developer's Guide</em>.
	         *
	         * @throws SecurityError If the <code>applicationDomain</code> or <code>securityDomain</code> 
	         * properties of the <code>context</code> parameter are from a disallowed domain.
	         * 
	         * @throws SecurityError If a local SWF file is attempting to use the <code>securityDomain</code> property
	         * of the <code>context</code> parameter.
	         *
	         * @throws IllegalOperationError If the <code>requestedContentParent</code> property of the <code>context</code> parameter
	         * is a <code>ProLoader</code>.
	         * 
	         * @throws IllegalOperationError If the <code>LoaderContext.parameters</code> parameter is
	         * set to non-null and has some values which are not Strings.
	         * 
	         * @event asyncError AsyncErrorEvent Dispatched by the <code>contentLoaderInfo</code> object if the
	         * <code>LoaderContext.requestedContentParent</code> property has been specified and it is not possible to add the
	         * loaded content as a child to the specified DisplayObjectContainer. This could happen if the loaded content is a
	         * <code>flash.display.AVM1Movie</code> or if the <code>addChild()</code> call to the requestedContentParent throws
	         * an error.
	         * 
	         * @event complete Event Dispatched by the <code>contentLoaderInfo</code> object when the file has 
	         * completed loading. The <code>complete</code> event is always dispatched after the <code>init</code> event.
	         * 
	         * @event httpStatus HTTPStatusEvent Dispatched by the <code>contentLoaderInfo</code> object when a network 
	         * request is made over HTTP and Flash Player can detect the HTTP status code.
	         * 
	         * @event init Event Dispatched by the <code>contentLoaderInfo</code> object when the properties and methods 
	         * of the loaded SWF file are accessible. The <code>init</code> event always precedes the <code>complete</code> 
	         * event.
	         * 
	         * @event ioError IOErrorEvent Dispatched by the <code>contentLoaderInfo</code> object when an input or output 
	         * error occurs that causes a load operation to fail.
	         * 
	         * @event open Event Dispatched by the <code>contentLoaderInfo</code> object when the loading operation starts.
	         * 
	         * @event progress ProgressEvent Dispatched by the <code>contentLoaderInfo</code> object as data is received 
	         * while load operation progresses.
	         * 
	         * @event securityError SecurityErrorEvent Dispatched by the <code>contentLoaderInfo</code> object if a SWF file 
	         * in the local-with-filesystem sandbox attempts to load content in the local-with-networking sandbox, or vice versa.
	         * 
	         * @event securityError SecurityErrorEvent Dispatched by the <code>contentLoaderInfo</code> object if the
	         * <code>LoaderContext.requestedContentParent</code> property has been specified and the security sandbox
	         * of the <code>LoaderContext.requestedContentParent</code> does not have access to the loaded SWF.
	         * 
	         * @event unload Event Dispatched by the <code>contentLoaderInfo</code> object when a loaded object is removed.
	         *
	         * @tiptext Loads a SWF file or image file into a DisplayObject that is a child of this ProLoader instance.
	         *
	         * @playerversion Flash 9
	         * @langversion 3.0
	         * 
	         * @oldexample The following example shows how to use the <code>MovieClipLoader.loadClip()</code> 
	         * method by creating a handler for the <code>onLoadInit</code> event and then making the request.
	         * <p>You should either place the following code directly into a frame action on a Timeline, or 
	         * paste it into a class that extends MovieClip. This code also expects an image named YourImage.jpg
	         * to exist in the same directory as the compiled SWF file.</p>
	         * 
	         * <listing version="2.0">
	         * var container:MovieClip = createEmptyMovieClip("container", getNextHighestDepth());
	         * var mcLoader:MovieClipLoader = new MovieClipLoader();
	         * mcLoader.addListener(this);
	         * mcLoader.loadClip("YourImage.jpg", container);
	         * 
	         * function onLoadInit(mc:MovieClip) {
	         *     trace("onLoadInit: " + mc);
	         * }
	         * </listing>
	         * 
	         * @see #contentLoaderInfo
	         * @see flash.net.URLRequest
	         * @see flash.display.DisplayObject
	         * @see fl.display.ProLoader#unload()
	         * @see fl.display.ProLoaderInfo
	         * @see flash.system.LoaderContext
	         * 
	         * @internal Need better wording and double-check verbiage for how Loader/DisplayObjects interact.
	         * @internal Double-check the "at"param verbiage for paths
	         *  		 
		 * @playerversion AIR 1.0
		 * @playerversion Flash Player 9
		 * @productversion Flash CS5.5
		 * @langversion 3.0
		 *
		 */
		public function load(request:URLRequest, context:LoaderContext=null):void {
			while (super.numChildren > 1) super.removeChildAt(1);
			_realContentLoader = null;
			_hasRequestedContentParentProp = false;
			_cli.reset();
			if (context == null) context = new LoaderContext();
			if (context.hasOwnProperty("requestedContentParent")) {
				_hasRequestedContentParentProp = true;
				var p:DisplayObjectContainer = context["requestedContentParent"];
				if (p == null) {
					context["requestedContentParent"] = this;
					_cli._lcRequestedContentParentSet = true;
				}
			}
			_loader.load(request, context);
			_loading = true;
		}

		 /**
	         * Loads from binary data stored in a ByteArray object.
	         *
	         * <p>The <code>loadBytes()</code> method is asynchronous. You must wait for the "init" event before
	         * accessing the properties of a loaded object.</p>
	         * 
	         * <p>When you use this method, consider the Flash Player security model,
	         *  which is described in the ProLoader class description. </p>
	         * 
	         * @param bytes A ByteArray object. The contents of the ByteArray can be 
	         * any of the file formats supported by the ProLoader class: SWF, GIF, JPEG, or PNG.
	         * 
	         * @param context A LoaderContext object. Only the <code>applicationDomain</code> property 
	         * of the LoaderContext object applies; the <code>checkPolicyFile</code> and <code>securityDomain</code> 
	         * properties of the LoaderContext object do not apply. 
	         *
	         * <p>If the <code>context</code> parameter is not 
	         * specified or refers to a null object, the content is loaded into the current security domain&#8212; a
	         * process referred to as "import loading" in Flash Player security documentation. Specifically, 
	         * if the loading SWF file trusts the remote SWF by incorporating the remote SWF into its code, 
	         * then the loading SWF can import it directly into its own security domain.</p>
	         *
	         * <p>For more information related to security, see the Flash Player Developer Center Topic: 
	         * <a href="http://www.adobe.com/go/devnet_security_en" target="external">Security</a>.</p>
	         *
	         * @playerversion Flash 9
	         * @langversion 3.0
	         *
	         * @throws ArgumentError If the <code>length</code> property of the ByteArray object is not
	         * greater than 0.
	         * 
	         * @throws IllegalOperationError If the <code>checkPolicyFile</code> or <code>securityDomain</code> 
	         * property of the <code>context</code> parameter are non-null.
	         *
	         * @throws IllegalOperationError If the <code>requestedContentParent</code> property of the <code>context</code> parameter
	         * is a <code>ProLoader</code>.
	         * 
	         * @throws IllegalOperationError If the <code>LoaderContext.parameters</code> parameter is
	         * set to non-null and has some values which are not Strings.
	         * 
	         * @throws SecurityError If the provided <code>applicationDomain</code> property of the 
	         * <code>context</code> property is from a disallowed domain.
	         * 
	         *  @throws SecurityError You cannot connect to commonly reserved ports. 
	         * For a complete list of blocked ports, see "Restricting Networking APIs" in the 
	         * <em>ActionScript 3.0 Developer's Guide</em>.
	         *
	         * @event asyncError AsyncErrorEvent Dispatched by the <code>contentLoaderInfo</code> object if the
	         * <code>LoaderContext.requestedContentParent</code> property has been specified and it is not possible to add the
	         * loaded content as a child to the specified DisplayObjectContainer. This could happen if the loaded content is a
	         * <code>flash.display.AVM1Movie</code> or if the <code>addChild()</code> call to the requestedContentParent throws
	         * an error.
	         * 
	         * @event complete Event Dispatched by the <code>contentLoaderInfo</code> object when the operation is 
	         * complete. The <code>complete</code> event is always dispatched after the <code>init</code> event.
	         * 
	         * @event init Event Dispatched by the <code>contentLoaderInfo</code> object when the properties and methods 
	         * of the loaded data are accessible. The <code>init</code> event always precedes the <code>complete</code> 
	         * event.
	         * 
	         * @event ioError IOErrorEvent Dispatched by the <code>contentLoaderInfo</code> object when the runtime cannot parse
	         * the data in the byte array. 
	         * 
	         * @event open Event Dispatched by the <code>contentLoaderInfo</code> object when the operation starts.
	         * 
	         * @event progress ProgressEvent Dispatched by the <code>contentLoaderInfo</code> object as data is transfered in memory. 
	         * 
	         * @event securityError SecurityErrorEvent Dispatched by the <code>contentLoaderInfo</code> object if the
	         * <code>LoaderContext.requestedContentParent</code> property has been specified and the security sandbox
	         * of the <code>LoaderContext.requestedContentParent</code> does not have access to the loaded SWF.
	         * 
	         * @event unload Event Dispatched by the <code>contentLoaderInfo</code> object when a loaded object is removed.
	         * 
	         * @see flash.utils.ByteArray
	         * @see flash.system.LoaderContext#applicationDomain
		 *
		 * @playerversion AIR 1.0
		 * @playerversion Flash 9
		 * @productversion Flash CS5.5
		 * @langversion 3.0
		 *
		 */
		public function loadBytes(bytes:ByteArray, context:LoaderContext=null):void {
			while (super.numChildren > 1) super.removeChildAt(1);
			_realContentLoader = null;
			_hasRequestedContentParentProp = false;
			_cli.reset();
			if (context == null) context = new LoaderContext();
			if (context.hasOwnProperty("requestedContentParent")) {
				_hasRequestedContentParentProp = true;
				var p:DisplayObjectContainer = context["requestedContentParent"];
				if (p == null) {
					context["requestedContentParent"] = this;
					_cli._lcRequestedContentParentSet = true;
				}
			}
			_loader.loadBytes(bytes, context);
			_loading = true;
		}

		/**
		 *
	 	 * Loads an IFilePromise instance through the <code>promise</code> parameter. The type of the <code>promise</code> parameter uses 
	 	 * the Object superclass instead of IFilePromise to avoid errors in other players.
	 	 * 
 	 	 * <p>The <code>loadFilePromise</code> method takes an <code>IFilePromise</code> object and 
	 	 * loads the binary data. If the data is a progressive stream, such as a video wait for the "init" 
	 	 * or progress events before accessing the properties of the loaded object. Otherwise, wait for 
	 	 * the complete event to make sure that the data is fully loaded.</p>
	 	 * 
	 	 * <p>When you use this method, consider the Flash Player security model,
	 	 *  which is described in the ProLoader class description. </p>
	 	 * 
	 	 * @param promise An IFilePromise object. The data source of the object can be 
	 	 * any of the file formats supported by the ProLoader class: SWF, GIF, JPEG, or PNG.
	 	 * 
	 	 * @param context A LoaderContext object. Only the <code>applicationDomain</code> property 
	 	 * of the LoaderContext object applies; the <code>checkPolicyFile</code> and <code>securityDomain</code> 
	 	 * properties of the LoaderContext object do not apply. 
	 	 *
	 	 * <p>If the <code>context</code> parameter is not 
	 	 * specified or refers to a null object, the content is loaded into the current security domain&#8212; a
	 	 * process referred to as "import loading" in Flash Player security documentation. Specifically, 
	 	 * if the loading SWF file trusts the remote SWF by incorporating the remote SWF into its code, 
	 	 * then the loading SWF can import it directly into its own security domain.</p>
	 	 *
	 	 * <p>For more information related to security, see the Flash Player Developer Center Topic: 
	 	 * <a href="http://www.adobe.com/go/devnet_security_en" target="external">Security</a>.</p>
	 	 *
	 	 * @playerversion AIR 2.5
	 	 * @langversion 3.0
	 	 *
     		 * @throws IllegalOperationError If the <code>requestedContentParent</code> property of the <code>context</code> parameter
     		 * is a <code>ProLoader</code> object.
     		 * 
     		 * @throws IllegalOperationError If the <code>LoaderContext.parameters</code> parameter is
     		 * set to non-null and has some values which are not Strings.
     		 * 
     		 * @throws ArgumentError If the <code>IFilePromise</code> object passed as parameter is null
     		 *
     		 * @event asyncError AsyncErrorEvent Dispatched by the <code>contentLoaderInfo</code> object if the
     		 * <code>LoaderContext.requestedContentParent</code> property has been specified and it is not possible to add the
     		 * loaded content as a child to the specified DisplayObjectContainer. This could happen if the loaded content is a
     		 * <code>flash.display.AVM1Movie</code> or if the <code>addChild()</code> call to the requestedContentParent throws
     		 * an error.
     		 * 
     		 * @event complete Event Dispatched by the <code>contentLoaderInfo</code> object when the operation is 
     		 * complete. The <code>complete</code> event is always dispatched after the <code>init</code> event.
     		 * 
     		 * @event init Event Dispatched by the <code>contentLoaderInfo</code> object when the properties and methods 
     		 * of the loaded data are accessible. The <code>init</code> event always precedes the <code>complete</code> 
     		 * event.
     		 * 
     		 * @event ioError IOErrorEvent Dispatched by the <code>contentLoaderInfo</code> object when the runtime cannot parse
     		 * the data in the data source or if the data source stream is not readable. 
     		 * 
     		 * @event open Event Dispatched by the <code>contentLoaderInfo</code> object when the operation starts.
     		 * 
     		 * @event progress ProgressEvent Dispatched by the <code>contentLoaderInfo</code> object as data is transfered in memory. 
     		 * 
     		 * @event securityError SecurityErrorEvent Dispatched by the <code>contentLoaderInfo</code> object if the
     		 * <code>LoaderContext.requestedContentParent</code> property has been specified and the security sandbox
     		 * of the <code>LoaderContext.requestedContentParent</code> does not have access to the loaded SWF.
     		 * 
     		 * @event unload Event Dispatched by the <code>contentLoaderInfo</code> object when a loaded object is removed.
		 * <p><b>Warning</b> Accessing this API when not in an AIR application results in an error.</p>

     		 * 
     		 * @see flash.media.MediaPromise MediaPromise
     		 * @see flash.media.CameraRoll#browseForImage() CameraRoll.browseForImage()
     		 * @see flash.media.CameraUI CameraUI
     		 *  
		 * @playerversion AIR 2.0
		 * @playerversion Flash 9
		 * @productversion Flash CS5.5
		 * @langversion 3.0
		 */
    	public function loadFilePromise(promise:Object, context:LoaderContext = null):void
		{
			while (super.numChildren > 1) super.removeChildAt(1);
			_realContentLoader = null;
			_hasRequestedContentParentProp = false;
			_cli.reset();
			if (context == null) context = new LoaderContext();
			if (context.hasOwnProperty("requestedContentParent")) {
				_hasRequestedContentParentProp = true;
				var p:DisplayObjectContainer = context["requestedContentParent"];
				if (p == null) {
					context["requestedContentParent"] = this;
					_cli._lcRequestedContentParentSet = true;
				}
			}
			_loader["loadFilePromise"](promise, context);
			_loading = true;
		}

		/**
		* Removes a child of this ProLoader object that was loaded by using the <code>load()</code> method. 
		* The <code>property</code> of the associated ProLoaderInfo object is reset to <code>null</code>.  
		* The child is not necessarily destroyed because other objects might have references to it; however,
		* it is no longer a child of the ProLoader object.
		*
		* <p>As a best practice, before you unload a child SWF file, you should explicitly
		* close any streams in the child SWF file's objects, such as LocalConnection, NetConnection,
		* NetStream, and Sound objects. Otherwise, audio in the child SWF file might continue to play, even
		* though the child SWF file was unloaded. To close streams in the child SWF file, add an event listener
		* to the child that listens for the <code>unload</code> event. When the parent calls
		* <code>ProLoader.unload()</code>, the <code>unload</code> event is dispatched to the child.
		* The following code shows how you might do this:</p>
<pre>
function closeAllStreams(evt:Event) { 
    myNetStream.close();
    mySound.close();
    myNetConnection.close();
    myLocalConnection.close();
}

myMovieClip.loaderInfo.addEventListener(Event.UNLOAD, closeAllStreams);</pre>
		*
		* @internal The funky-looking code formatting above is intentional to work around a bug!
		* 
		* @playerversion AIR 1.0
		* @playerversion Flash 9
		* @productversion Flash CS5.5
		* @langversion 3.0
		*
		* @see fl.display.ProLoader#load()
		* @see flash.media.Sound#close()
		* @see flash.net.LocalConnection#close()
		* @see flash.net.NetConnection#close()
		* @see flash.net.NetStream#close()
		* @see ../../operators.html#delete delete operator
		*  
		*/
		public function unload():void {
			if (!_loading) {
				while (super.numChildren > 1) super.removeChildAt(1);
				_loader.unload();
			}
		}

		/**
     		 * Attempts to unload child SWF file contents and stops the execution of commands from loaded SWF files. 
     		 * This method attempts to unload SWF files
     		 * that were loaded using <code>ProLoader.load()</code> or <code>ProLoader.loadBytes()</code> by removing references to EventDispatcher,
     		 * NetConnection, Timer, Sound, or Video objects of the child SWF file. As a result, the following occurs for the child SWF file
     		 * and the child SWF file's display list:
     		 * <ul><li>Sounds are stopped.</li>
     		 * <li>Stage event listeners are removed.</li>
     		 * <li>Event listeners for <code>enterFrame</code>, <code>frameConstructed</code>, <code>exitFrame</code>,
     		 * <code>activate</code> and <code>deactivate</code> are removed.</li>
     		 * <li>Timers are stopped.</li>
     		 * <li>Camera and Microphone instances are detached</li>
     		 * <li>Movie clips are stopped.</li></ul>
     		 * @param gc Provides a hint to the garbage collector to run on the child SWF objects (<code>true</code>) or not (<code>false</code>).
     		 * If you are unloading many objects asynchronously, setting the <code>gc</code> paramter to <code>false</code> might improve 
     		 * application performance. However, if the parameter is set to 
     		 * <code>false</code>, media and display objects of the child SWF file might persist in memory after running the 
     		 * <code>unloadAndStop()</code> command.
		 * <p><b>Warning</b> Accessing this API in a player that does not support it results in an error.</p>
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
		 * @productversion Flash CS5.5
		 * @langversion 3.0
		 * @see flash.display.DisplayObject
		 * @see fl.display.ProLoader#load()
		 * 
		public function unloadAndStop(gc:Boolean=true):void {
			if (!_loading) {
				while (super.numChildren > 1) super.removeChildAt(1);
				_loader["unloadAndStop"](gc);
			}
		}

		/**
		 * mimic the way flash.display.Loader disallows children to be added, removed
		 * @private
		 */
		public override function addChild(c:DisplayObject):DisplayObject
		{
			if ( (_realContentLoader != null && _realContentLoader.content == c) || _loader.content == c ) {
				return super.addChild(c);
			}
			throw new Error("Error #2069: The ProLoader class does not implement this method.");
			return null; // unreachable
		 }
		/**
		 * mimic the way flash.display.Loader disallows children to be added, removed
		 * @private
		 */
		 public override function addChildAt(c:DisplayObject, i:int):DisplayObject {
			 throw new Error("Error #2069: The ProLoader class does not implement this method.");
		 }
		/**
		 * mimic the way flash.display.Loader disallows children to be added, removed
		 * @private
		 */
		 public override function removeChild(c:DisplayObject):DisplayObject {
			 throw new Error("Error #2069: The ProLoader class does not implement this method.");
		 }
		/**
		 * mimic the way flash.display.Loader disallows children to be added, removed
		 * @private
		 */
		 public override function removeChildAt(i:int):DisplayObject {
			 throw new Error("Error #2069: The ProLoader class does not implement this method.");
		 }
		/**
		 * mimic the way flash.display.Loader disallows children to be added, removed
		 * @private
		 */
		 public override function setChildIndex(c:DisplayObject, i:int):void {
			 throw new Error("Error #2069: The ProLoader class does not implement this method.");
		 }

		/**
		 * since we keep the invisible Loader on stage all the time, don't count it
		 * @private
		 */
		public override function get numChildren():int {
			return super.numChildren - 1;
		}

		/**
		 * since we keep the invisible Loader on stage all the time, don't count it
		 * @private
		 */
		public override function getChildAt(index:int):DisplayObject {
			if (index >= 0) index++;
			return super.getChildAt(index);
		}

		/**
		 * since we keep the invisible Loader on stage all the time, don't count it
		 * @private
		 */
		public override function getChildIndex(d:DisplayObject):int {
			return super.getChildIndex(d) - 1;
		}

		/**
           	 * An object that dispatches an <code>uncaughtError</code> event when an unhandled error 
        	 * occurs in code in this ProLoader object's SWF file. An uncaught error happens when 
        	 * an error is thrown outside of any <code>try..catch</code> blocks or when an ErrorEvent 
        	 * object is dispatched with no registered listeners.
        	 * 
        	 * <p>This property is created when the SWF associated with this object has finished 
        	 * loading. Until then the <code>uncaughtErrorEvents</code> property is <code>null</code>.
        	 * In an ActionScript-only project, you can access this property during or after the execution
        	 * of the constructor function of the main class of the SWF file.</p>
        	 * 
		 * <p>Accessing this ProLoader property in a player that does not support
		 * it results in an error. Returns an EventDispatcher object instead
		 * of an UncaughtErrorEvents object to avoid generating errors in unsupporting players.</p>
        	 *
          	 * @see flash.display.LoaderInfo#uncaughtErrorEvents
                 * 
		 * @playerversion Flash 10.1
		 * @playerversion AIR 2.0
		 * @productversion Flash CS5.5
		 * @langversion 3.0
		 */
		public function get uncaughtErrorEvents():EventDispatcher
		{
			return _loader["uncaughtErrorEvents"];
		}

	}
}