/// <summary>
        /// Reloads the specified asset.
        /// </summary>
        /// <param name="assetName">Name of the asset to load</param>
        /// <returns>The new reference to the reloaded asset</returns>
        public object Reload(string assetName, AssetLoadedHandler Callback)
        {
            if (mCache.ContainsKey(assetName))
            {
                AssetTracker oldAssetTracker = mCache[assetName];

                // Remove tracker so Load<T>() will create a new one
                mCache.Remove(assetName);
                mCacheNames.Remove(assetName);

                // Load it again
                object asset = Load(assetName, Callback);

                // Invoke AssetChanged event
                oldAssetTracker.OnAssetChanged(new AssetChangedEventArgs(asset));

                // Destroy previous tracker
                DisposeAssetTracker(oldAssetTracker, true);

                return(asset);
            }
            else
            {
                return(Load(assetName, Callback));
            }
        }
        /// <summary>
        /// Force an asset to be disposed. Optionally releases child assets
        /// </summary>
        /// <param name="assetName">Name of asset to unload</param>
        /// <param name="releaseChildren">Release child assets</param>
        public void Unload(string assetName, bool releaseChildren)
        {
            if (mCache.ContainsKey(assetName))
            {
                AssetTracker tracker = mCache[assetName];

                // Fire changed event
                tracker.OnAssetChanged(new AssetChangedEventArgs(null));

                // Destroy disposables
                DisposeAssetTracker(tracker, releaseChildren);

                // Remove from dictionary
                mCache.Remove(assetName);
                mCacheNames.Remove(assetName);
            }
        }
        /// <summary>
        /// Release asset. Decrements the reference count and
        /// removes child assets when the count is zero
        /// </summary>
        /// <param name="assetName">Asset to release</param>
        public void Release(string assetName)
        {
            if (mCache.ContainsKey(assetName))
            {
                AssetTracker tracker = mCache[assetName];
                tracker.RefCount--;

                if (tracker.RefCount == 0)
                {
                    tracker.OnAssetChanged(new AssetChangedEventArgs(null));
                    DisposeAssetTracker(tracker, true);

                    // Remove from dictionary
                    mCache.Remove(assetName);
                    mCacheNames.Remove(assetName);
                }
            }
        }
        /// <summary>
        /// Destroy IDisposables that were tracked by this asset but do not
        /// exist as assets in their own right. This will also dispose the
        /// unmanaged internals like vertex and index buffers
        /// </summary>
        /// <param name="tracker">AssetTracker to dispose</param>
        /// <param name="releaseChildren">If true, child assets will be released</param>
        private void DisposeAssetTracker(AssetTracker tracker, bool releaseChildren)
        {
            // Invoke asset changed event.
            tracker.OnAssetChanged(new AssetChangedEventArgs(null));

            // Mark tracker as disposed
            tracker.Status = EAssetStatus.Disposed;

            // Destroy tracked disposables
            foreach (IDisposable disposable in tracker.Disposables)
            {
                disposable.Dispose();
            }

            // Dispose the actual asset, if possible
            if (tracker.Asset is IDisposable)
            {
                ((IDisposable)tracker.Asset).Dispose();
            }

            // Handle child assets
            foreach (string childAsset in tracker.RefersTo)
            {
                if (mCache.ContainsKey(childAsset))
                {
                    // Maintain child reference list
                    mCache[childAsset].ReferredToBy.Remove(tracker.AssetName);

                    // release child assets if requested
                    if (releaseChildren)
                    {
                        Release(childAsset);
                    }
                }
            }
        }
		/// <summary>
		/// Destroy IDisposables that were tracked by this asset but do not 
		/// exist as assets in their own right. This will also dispose the
		/// unmanaged internals like vertex and index buffers
		/// </summary>
		/// <param name="tracker">AssetTracker to dispose</param>
		/// <param name="releaseChildren">If true, child assets will be released</param>
		private void DisposeAssetTracker( AssetTracker tracker, bool releaseChildren ) {
			// Invoke asset changed event.
			tracker.OnAssetChanged( new AssetChangedEventArgs( null ) );

			// Mark tracker as disposed
			tracker.Status = EAssetStatus.Disposed;

			// Destroy tracked disposables
			foreach( IDisposable disposable in tracker.Disposables ) {
				disposable.Dispose();
			}

			// Dispose the actual asset, if possible
			if( tracker.Asset is IDisposable )
				( (IDisposable)tracker.Asset ).Dispose();

			// Handle child assets
			foreach( string childAsset in tracker.RefersTo ) {
				if( mCache.ContainsKey( childAsset ) ) {
					// Maintain child reference list
					mCache[ childAsset ].ReferredToBy.Remove( tracker.AssetName );

					// release child assets if requested
					if( releaseChildren )
						Release( childAsset );
				}
			}
		}