Merge pull request #2087 from joelmartinez/mdoc-membername-fixup
[mono.git] / mcs / class / System.Web / System.Web / HttpRuntime.cs
index cd81320340ad1e785524bef108cc4a1376963391..d2822357434e406f738d294a8269f02c512fea75 100644 (file)
@@ -1,11 +1,12 @@
 //
 // System.Web.HttpRuntime.cs 
 // 
-// Author:
+// Authors:
 //     Miguel de Icaza (miguel@novell.com)
+//      Marek Habersack <mhabersack@novell.com>
 //
 //
-// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2005-2010 Novell, Inc (http://www.novell.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -34,88 +35,108 @@ using System.IO;
 using System.Text;
 using System.Globalization;
 using System.Collections;
+using System.Collections.Concurrent;
+using System.Reflection;
 using System.Security;
 using System.Security.Permissions;
 using System.Web.Caching;
 using System.Web.Configuration;
+using System.Web.Management;
 using System.Web.UI;
+using System.Web.Util;
+using Mono.Web.Util;
 using System.Threading;
-
-#if NET_2_0 && !TARGET_JVM
 using System.CodeDom.Compiler;
 using System.Web.Compilation;
-#endif
 
-namespace System.Web {
-       
+namespace System.Web
+{      
        // CAS - no InheritanceDemand here as the class is sealed
        [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
-       public sealed class HttpRuntime {
-#if TARGET_J2EE
-               static QueueManager queue_manager { get { return _runtime._queue_manager; } }
-               static TraceManager trace_manager { get { return _runtime._trace_manager; } }
-               static Cache cache { get { return _runtime._cache; } }
+       public sealed class HttpRuntime
+       {
+               static bool domainUnloading;
+               static SplitOrderedList <string, string> registeredAssemblies;
+               static QueueManager queue_manager;
+               static TraceManager trace_manager;
+               static Cache cache;
+               static Cache internalCache;
                static WaitCallback do_RealProcessRequest;
-
-               QueueManager _queue_manager;
-               TraceManager _trace_manager;
-               Cache _cache;
-
-               static HttpRuntime ()
-               {
-                       do_RealProcessRequest = new WaitCallback (RealProcessRequest);
-               }
-
+               static HttpWorkerRequest.EndOfSendNotification end_of_send_cb;
+               static Exception initialException;
+               static bool firstRun;
+               static bool assemblyMappingEnabled;
+               static object assemblyMappingLock = new object ();
+               static object appOfflineLock = new object ();
+               static HttpRuntimeSection runtime_section;
+               
                public HttpRuntime ()
                {
-                       WebConfigurationManager.Init ();
-                       _queue_manager = new QueueManager ();
-                       _trace_manager = new TraceManager ();
-                       _cache = new Cache ();
-               }
 
-               static private HttpRuntime _runtime {
-                       get {
-                               HttpRuntime runtime = (HttpRuntime)AppDomain.CurrentDomain.GetData("HttpRuntime");
-                               if (runtime == null)
-                                       lock (typeof(HttpRuntime)) {
-                                               runtime = (HttpRuntime)AppDomain.CurrentDomain.GetData("HttpRuntime");
-                                               if (runtime == null) {
-                                                       runtime = new HttpRuntime();
-                                                       AppDomain.CurrentDomain.SetData("HttpRuntime", runtime);
-                                               }
-                                       }
-                               return runtime;
-                       }
                }
-#else
-               static QueueManager queue_manager;
-               static TraceManager trace_manager;
-               static TimeoutManager timeout_manager;
-               static Cache cache;
-               static WaitCallback do_RealProcessRequest;
 
                static HttpRuntime ()
                {
-#if NET_2_0
-                       WebConfigurationManager.Init ();
-#endif
+                       firstRun = true;
+
+                       try {
+                               WebConfigurationManager.Init ();
+                               SettingsMappingManager.Init ();
+                               runtime_section = (HttpRuntimeSection) WebConfigurationManager.GetSection ("system.web/httpRuntime");
+                       } catch (Exception ex) {
+                               initialException = ex;
+                       }
+
+                       // The classes in whose constructors exceptions may be thrown, should be handled the same way QueueManager
+                       // and TraceManager are below. The constructors themselves MUST NOT throw any exceptions - we MUST be sure
+                       // the objects are created here. The exceptions will be dealt with below, in RealProcessRequest.
                        queue_manager = new QueueManager ();
+                       if (queue_manager.HasException) {
+                               if (initialException == null)
+                                       initialException = queue_manager.InitialException;
+                               else {
+                                       Console.Error.WriteLine ("Exception during QueueManager initialization:");
+                                       Console.Error.WriteLine (queue_manager.InitialException);
+                               }
+                       }
+
                        trace_manager = new TraceManager ();
-                       timeout_manager = new TimeoutManager ();
+                       if (trace_manager.HasException) {
+                               if (initialException == null)
+                                       initialException = trace_manager.InitialException;
+                               else {
+                                       Console.Error.WriteLine ("Exception during TraceManager initialization:");
+                                       Console.Error.WriteLine (trace_manager.InitialException);
+                               }
+                       }
+
+                       registeredAssemblies = new SplitOrderedList <string, string> (StringComparer.Ordinal);
                        cache = new Cache ();
-                       do_RealProcessRequest = new WaitCallback (RealProcessRequest);
+                       internalCache = new Cache ();
+                       internalCache.DependencyCache = internalCache;
+                       do_RealProcessRequest = new WaitCallback (state => {
+                               try {
+                                       RealProcessRequest (state);
+                               } catch {}
+                               });
+                       end_of_send_cb = new HttpWorkerRequest.EndOfSendNotification (EndOfSend);
                }
 
-#if ONLY_1_1
-               [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
-#endif
-               public HttpRuntime ()
-               {
+               internal static SplitOrderedList <string, string> RegisteredAssemblies {
+                       get { return registeredAssemblies; }
                }
-#endif
-
+               
 #region AppDomain handling
+               internal static bool DomainUnloading {
+                       get { return domainUnloading; }
+               }
+
+               [MonoDocumentationNote ("Currently returns path to the application root")]
+               public static string AspClientScriptPhysicalPath { get { return AppDomainAppPath; } }
+
+               [MonoDocumentationNote ("Currently returns path to the application root")]
+               public static string AspClientScriptVirtualPath { get { return AppDomainAppVirtualPath; } }
+               
                //
                // http://radio.weblogs.com/0105476/stories/2002/07/12/executingAspxPagesWithoutAWebServer.html
                //
@@ -167,14 +188,34 @@ namespace System.Web {
                        }
                }
 #endregion
-               
+
+               static string _actual_bin_directory;
                public static string BinDirectory {
                        get {
-                               string dirname = Path.Combine (AppDomainAppPath, "bin");
-                               if (SecurityManager.SecurityEnabled) {
-                                       new FileIOPermission (FileIOPermissionAccess.PathDiscovery, dirname).Demand ();
+                               if (_actual_bin_directory == null) {
+                                       string[] parts = AppDomain.CurrentDomain.SetupInformation.PrivateBinPath.Split (';');
+                                       string mypath = AppDomainAppPath;
+                                       string tmp;
+                                       
+                                       foreach (string p in parts) {
+                                               tmp = Path.Combine (mypath, p);
+                                               if (Directory.Exists (tmp)) {
+                                                       _actual_bin_directory = tmp;
+                                                       break;
+                                               }
+                                       }
+
+                                       if (_actual_bin_directory == null)
+                                               _actual_bin_directory = Path.Combine (mypath, "bin");
+
+                                       if (_actual_bin_directory [_actual_bin_directory.Length - 1] != Path.DirectorySeparatorChar)
+                                               _actual_bin_directory += Path.DirectorySeparatorChar;
                                }
-                               return dirname;
+                               
+                               if (SecurityManager.SecurityEnabled)
+                                       new FileIOPermission (FileIOPermissionAccess.PathDiscovery, _actual_bin_directory).Demand ();
+
+                               return _actual_bin_directory;
                        }
                }
 
@@ -184,6 +225,12 @@ namespace System.Web {
                        }
                }
 
+               internal static Cache InternalCache {
+                       get {
+                               return internalCache;
+                       }
+               }
+               
                public static string ClrInstallDirectory {
                        get {
                                string dirname = Path.GetDirectoryName (typeof (Object).Assembly.Location);
@@ -204,21 +251,16 @@ namespace System.Web {
                        }
                }
 
-               [MonoTODO]
                public static bool IsOnUNCShare {
                        [AspNetHostingPermission (SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Low)]
                        get {
-                               throw new NotImplementedException ();
+                               return RuntimeHelpers.IsUncShare;
                        }
                }
 
                public static string MachineConfigurationDirectory {
                        get {
-#if NET_2_0
-                               string dirname = Path.GetDirectoryName (WebConfigurationManager.OpenMachineConfiguration().FilePath);
-#else
-                               string dirname = Path.GetDirectoryName (WebConfigurationSettings.MachineConfigPath);
-#endif
+                               string dirname = Path.GetDirectoryName (ICalls.GetMachineConfigPath ());
                                if ((dirname != null) && (dirname.Length > 0) && SecurityManager.SecurityEnabled) {
                                        new FileIOPermission (FileIOPermissionAccess.PathDiscovery, dirname).Demand ();
                                }
@@ -226,66 +268,219 @@ namespace System.Web {
                        }
                }
 
+               internal static HttpRuntimeSection Section { get { return runtime_section; } }
+
+               public static bool UsingIntegratedPipeline { get { return false; } }
+
+               public static Version IISVersion {
+                       get {
+                               // Null means not hosted by IIS
+                               return null;
+                       }
+               }
+               
+               public static Version TargetFramework {
+                       get {
+                               return runtime_section.TargetFramework;
+                       }
+               }
+               
                [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
                public static void Close ()
                {
                        // Remove all items from cache.
                }
 
-               static void QueuePendingRequests ()
+               internal static HttpWorkerRequest QueuePendingRequest (bool started_internally)
                {
-                       HttpWorkerRequest request = queue_manager.GetNextRequest (null);
-                       if (request == null)
-                               return;
-                       ThreadPool.QueueUserWorkItem (do_RealProcessRequest, request);
+                       HttpWorkerRequest next = queue_manager.GetNextRequest (null);
+                       if (next == null)
+                               return null;
+
+                       if (!started_internally) {
+                               next.StartedInternally = true;
+                               ThreadPool.QueueUserWorkItem (do_RealProcessRequest, next);
+                               return null;
+                       }
+                       return next;
+               }
+
+               static readonly string[] app_offline_files = {"app_offline.htm", "App_Offline.htm", "APP_OFFLINE.HTM"};
+               static string app_offline_file;
+               
+               static bool AppIsOffline (HttpContext context)
+               {
+                       if (!HttpApplicationFactory.ApplicationDisabled || app_offline_file == null)
+                               return false;
+
+                       HttpResponse response = context.Response;
+                       response.Clear ();
+                       response.ContentType = "text/html";
+                       response.ExpiresAbsolute = DateTime.UtcNow;
+                       response.StatusCode = 503;
+                       response.TransmitFile (app_offline_file, true);
+                       
+                       context.Request.ReleaseResources ();
+                       context.Response.ReleaseResources ();
+                       HttpContext.Current = null;
+                       HttpApplication.requests_total_counter.Increment ();
+                       
+                       return true;
+               }
+
+               static void AppOfflineFileRenamed (object sender, RenamedEventArgs args)
+               {
+                       AppOfflineFileChanged (sender, args);
                }
 
+               static void AppOfflineFileChanged (object sender, FileSystemEventArgs args)
+               {
+                       lock (appOfflineLock) {
+                               bool offline;
+                               
+                               switch (args.ChangeType) {
+                                       case WatcherChangeTypes.Created:
+                                       case WatcherChangeTypes.Changed:
+                                               offline = true;
+                                               break;
+
+                                       case WatcherChangeTypes.Deleted:
+                                               offline = false;
+                                               break;
+
+                                       case WatcherChangeTypes.Renamed:
+                                               RenamedEventArgs rargs = args as RenamedEventArgs;
+
+                                               if (rargs != null &&
+                                                   String.Compare (rargs.Name, "app_offline.htm", StringComparison.OrdinalIgnoreCase) == 0)
+                                                       offline = true;
+                                               else
+                                                       offline = false;
+                                               break;
+
+                                       default:
+                                               offline = false;
+                                               break;
+                               }
+                               SetOfflineMode (offline, args.FullPath);
+                       }
+               }
+
+               static void SetOfflineMode (bool offline, string filePath)
+               {
+                       if (!offline) {
+                               app_offline_file = null;
+                               if (HttpApplicationFactory.ApplicationDisabled)
+                                       HttpRuntime.UnloadAppDomain ();
+                       } else {
+                               app_offline_file = filePath;
+                               HttpApplicationFactory.DisableWatchers ();
+                               HttpApplicationFactory.ApplicationDisabled = true;
+                               InternalCache.InvokePrivateCallbacks ();
+                               HttpApplicationFactory.Dispose ();
+                       }
+               }
+               
+               static void SetupOfflineWatch ()
+               {
+                       lock (appOfflineLock) {
+                               FileSystemEventHandler seh = new FileSystemEventHandler (AppOfflineFileChanged);
+                               RenamedEventHandler reh = new RenamedEventHandler (AppOfflineFileRenamed);
+
+                               string app_dir = AppDomainAppPath;
+                               FileSystemWatcher watcher;
+                               string offlineFile = null, tmp;
+                               
+                               foreach (string f in app_offline_files) {
+                                       watcher = new FileSystemWatcher ();
+                                       watcher.Path = Path.GetDirectoryName (app_dir);
+                                       watcher.Filter = Path.GetFileName (f);
+                                       watcher.NotifyFilter |= NotifyFilters.Size;
+                                       watcher.Deleted += seh;
+                                       watcher.Changed += seh;
+                                       watcher.Created += seh;
+                                       watcher.Renamed += reh;
+                                       watcher.EnableRaisingEvents = true;
+
+                                       tmp = Path.Combine (app_dir, f);
+                                       if (File.Exists (tmp))
+                                               offlineFile = tmp;
+                               }
+
+                               if (offlineFile != null)
+                                       SetOfflineMode (true, offlineFile);
+                       }
+               }
+               
                static void RealProcessRequest (object o)
                {
-                       HttpContext context = new HttpContext ((HttpWorkerRequest) o);
-                       HttpContext.Current = context;
+                       if (domainUnloading) {
+                               Console.Error.WriteLine ("Domain is unloading, not processing the request.");
+                               return;
+                       }
+
+                       HttpWorkerRequest req = (HttpWorkerRequest) o;
+                       bool started_internally = req.StartedInternally;
+                       do {
+                               Process (req);
+                               req = QueuePendingRequest (started_internally);
+                       } while (started_internally && req != null);
+               }
 
+               static void Process (HttpWorkerRequest req)
+               {
+                       bool error = false;
+                       if (firstRun) {
+                               firstRun = false;
+                               if (initialException != null) {
+                                       FinishWithException (req, HttpException.NewWithCode ("Initial exception", initialException, WebEventCodes.RuntimeErrorRequestAbort));
+                                       error = true;
+                               }
+                               SetupOfflineWatch ();
+                       }
+                       HttpContext context = new HttpContext (req);
+                       HttpContext.Current = context;
+                       if (AppIsOffline (context))
+                               return;
+                       
                        //
                        // Get application instance (create or reuse an instance of the correct class)
                        //
                        HttpApplication app = null;
-                       bool error = false;
-                       try {
-                               app = HttpApplicationFactory.GetApplication (context);
-                       } catch (Exception e) {
-                               FinishWithException ((HttpWorkerRequest) o, new HttpException ("", e));
-                               error = true;
+                       if (!error) {
+                               try {
+                                       app = HttpApplicationFactory.GetApplication (context);
+                               } catch (Exception e) {
+                                       FinishWithException (req, HttpException.NewWithCode (String.Empty, e, WebEventCodes.RuntimeErrorRequestAbort));
+                                       error = true;
+                               }
                        }
-
+                       
                        if (error) {
                                context.Request.ReleaseResources ();
                                context.Response.ReleaseResources ();
                                HttpContext.Current = null;
                        } else {
                                context.ApplicationInstance = app;
-                       
-#if NET_2_0 && !TARGET_JVM
-                               //
-                               // Compile the local resources, if any
-                               //
-                               AppResourcesCompiler ac = new AppResourcesCompiler (context, false);
-                               ac.Compile ();
-#endif
-                               
+                               req.SetEndOfSendNotification (end_of_send_cb, context);
+
                                //
                                // Ask application to service the request
                                //
-                               IHttpAsyncHandler ihah = app;
-
-                               IAsyncResult appiar = ihah.BeginProcessRequest (context, new AsyncCallback (request_processed), context);
-                               ihah.EndProcessRequest (appiar);
+                               
+                               IHttpHandler ihh = app;
+//                             IAsyncResult appiar = ihah.BeginProcessRequest (context, new AsyncCallback (request_processed), context);
+//                             ihah.EndProcessRequest (appiar);
+                               ihh.ProcessRequest (context);
 
                                HttpApplicationFactory.Recycle (app);
                        }
-                       
-                       QueuePendingRequests ();
                }
-               
+
+               static void EndOfSend (HttpWorkerRequest ignored1, object ignored2)
+               {
+               }
+
                //
                // ProcessRequest method is executed in the AppDomain of the application
                //
@@ -305,20 +500,11 @@ namespace System.Web {
                        if (request == null)
                                return;
 
+                       QueuePendingRequest (false);
                        RealProcessRequest (request);
                }
 
-               //
-               // Callback to be invoked by IHttpAsyncHandler.BeginProcessRequest
-               //
-               static void request_processed (IAsyncResult iar)
-               {
-                       HttpContext context = (HttpContext) iar.AsyncState;
-
-                       context.Request.ReleaseResources ();
-                       context.Response.ReleaseResources ();
-               }
-
+               
                //
                // Called when we are shutting down or we need to reload an application
                // that has been modified (touch global.asax) 
@@ -329,34 +515,39 @@ namespace System.Web {
                        //
                        // TODO: call ReleaseResources
                        //
-                       ThreadPool.QueueUserWorkItem (new WaitCallback (ShutdownAppDomain), null);
+                       domainUnloading = true;
+                       HttpApplicationFactory.DisableWatchers ();
+                       ThreadPool.QueueUserWorkItem (delegate {
+                               try {
+                                       ShutdownAppDomain ();
+                               } catch (Exception e){
+                                       Console.Error.WriteLine (e);
+                               }
+                       });
                }
-
                //
                // Shuts down the AppDomain
                //
-               static void ShutdownAppDomain (object args)
+               static void ShutdownAppDomain ()
                {
                        queue_manager.Dispose ();
                        // This will call Session_End if needed.
-                       Cache.InvokePrivateCallbacks ();
+                       InternalCache.InvokePrivateCallbacks ();
                        // Kill our application.
                        HttpApplicationFactory.Dispose ();
-                       ThreadPool.QueueUserWorkItem (new WaitCallback (DoUnload), null);
+                       ThreadPool.QueueUserWorkItem (delegate {
+                               try {
+                                       DoUnload ();
+                               } catch {
+                               }});
                }
 
-#if TARGET_J2EE // No unload support for appdomains under Grasshopper
-               static void DoUnload (object state)
-               {
-               }
-#else
-               static void DoUnload (object state)
+               static void DoUnload ()
                {
                        AppDomain.Unload (AppDomain.CurrentDomain);
                }
-#endif
 
-                static string content503 = "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n" +
+               static string content503 = "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n" +
                        "<html><head>\n<title>503 Server Unavailable</title>\n</head><body>\n" +
                        "<h1>Server Unavailable</h1>\n" +
                        "</body></html>\n";
@@ -366,7 +557,6 @@ namespace System.Web {
                        int code = e.GetHttpCode ();
                        wr.SendStatus (code, HttpWorkerRequest.GetStatusDescription (code));
                        wr.SendUnknownResponseHeader ("Connection", "close");
-                       wr.SendUnknownResponseHeader ("Date", DateTime.Now.ToUniversalTime ().ToString ("r"));
                        Encoding enc = Encoding.ASCII;
                        wr.SendUnknownResponseHeader ("Content-Type", "text/html; charset=" + enc.WebName);
                        string msg = e.GetHtmlErrorMessage ();
@@ -375,6 +565,7 @@ namespace System.Web {
                        wr.SendResponseFromMemory (contentBytes, contentBytes.Length);
                        wr.FlushResponse (true);
                        wr.CloseConnection ();
+                       HttpApplication.requests_total_counter.Increment ();
                }
 
                //
@@ -386,7 +577,6 @@ namespace System.Web {
                {
                        wr.SendStatus (503, "Service unavailable");
                        wr.SendUnknownResponseHeader ("Connection", "close");
-                       wr.SendUnknownResponseHeader ("Date", DateTime.Now.ToUniversalTime ().ToString ("r"));
                        Encoding enc = Encoding.ASCII;
                        wr.SendUnknownResponseHeader ("Content-Type", "text/html; charset=" + enc.WebName);
                        byte [] contentBytes = enc.GetBytes (content503);
@@ -394,20 +584,93 @@ namespace System.Web {
                        wr.SendResponseFromMemory (contentBytes, contentBytes.Length);
                        wr.FlushResponse (true);
                        wr.CloseConnection ();
+                       HttpApplication.requests_total_counter.Increment ();
                }
 
-               internal static TraceManager TraceManager {
-                       get {
-                               return trace_manager;
+               [AspNetHostingPermissionAttribute(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Unrestricted)]
+               [MonoDocumentationNote ("Always returns null on Mono")]
+               public static NamedPermissionSet GetNamedPermissionSet ()
+               {
+                       return null;
+               }
+               
+               static internal void WritePreservationFile (Assembly asm, string genericNameBase)
+               {
+                       if (asm == null)
+                               throw new ArgumentNullException ("asm");
+                       if (String.IsNullOrEmpty (genericNameBase))
+                               throw new ArgumentNullException ("genericNameBase");
+
+                       string compiled = Path.Combine (AppDomain.CurrentDomain.SetupInformation.DynamicBase,
+                                                       genericNameBase + ".compiled");
+                       PreservationFile pf = new PreservationFile ();
+                       try {
+                               pf.VirtualPath = String.Concat ("/", genericNameBase, "/");
+
+                               AssemblyName an = asm.GetName ();
+                               pf.Assembly = an.Name;
+                               pf.ResultType = BuildResultTypeCode.TopLevelAssembly;
+                               pf.Save (compiled);
+                       } catch (Exception ex) {
+                               throw new HttpException (
+                                       String.Format ("Failed to write preservation file {0}", genericNameBase + ".compiled"),
+                                       ex);
                        }
                }
+               
+               static Assembly ResolveAssemblyHandler(object sender, ResolveEventArgs e)
+               {
+                       AssemblyName an = new AssemblyName (e.Name);
+                       string dynamic_base = AppDomain.CurrentDomain.SetupInformation.DynamicBase;
+                       string compiled = Path.Combine (dynamic_base, an.Name + ".compiled");
+                       string asmPath;
+
+                       if (!File.Exists (compiled)) {
+                               string fn = an.FullName;
+                               if (!RegisteredAssemblies.Find ((uint)fn.GetHashCode (), fn, out asmPath))
+                                       return null;
+                       } else {
+                               PreservationFile pf;
+                               try {
+                                       pf = new PreservationFile (compiled);
+                               } catch (Exception ex) {
+                                       throw new HttpException (
+                                               String.Format ("Failed to read preservation file {0}", an.Name + ".compiled"),
+                                               ex);
+                               }
+                               asmPath = Path.Combine (dynamic_base, pf.Assembly + ".dll");
+                       }
 
-#if !TARGET_JVM
-               internal static TimeoutManager TimeoutManager {
+                       if (String.IsNullOrEmpty (asmPath))
+                               return null;
+                       
+                       Assembly ret = null;
+                       try {
+                               ret = Assembly.LoadFrom (asmPath);
+                       } catch (Exception) {
+                               // ignore
+                       }
+                       
+                       return ret;
+               }
+               
+               internal static void EnableAssemblyMapping (bool enable)
+               {
+                       lock (assemblyMappingLock) {
+                               if (assemblyMappingEnabled == enable)
+                                       return;
+                               if (enable)
+                                       AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler (ResolveAssemblyHandler);
+                               else
+                                       AppDomain.CurrentDomain.AssemblyResolve -= new ResolveEventHandler (ResolveAssemblyHandler);
+                               assemblyMappingEnabled = enable;
+                       }
+               }
+               
+               internal static TraceManager TraceManager {
                        get {
-                               return timeout_manager;
+                               return trace_manager;
                        }
                }
-#endif
        }
 }