New tests.
[mono.git] / mcs / class / corlib / System / AppDomain.cs
index 5cf2e5a45477a439b703e192a11cb1068f802f09..b2e1e57f46f218ea7b49f2c76761a688db3e972e 100644 (file)
@@ -50,19 +50,27 @@ using System.Security.Policy;
 using System.Security.Principal;
 using System.Configuration.Assemblies;
 
-#if NET_2_0
+using System.Collections.Generic;
 using System.Runtime.ConstrainedExecution;
-#endif
+using System.Text;
 
 namespace System {
 
-#if NET_2_0
        [ComVisible (true)]
+#if !NET_2_1
+       [ComDefaultInterface (typeof (_AppDomain))]
 #endif
        [ClassInterface(ClassInterfaceType.None)]
-       public sealed class AppDomain : MarshalByRefObject , _AppDomain , IEvidenceFactory
-       {
+#if NET_2_1
+       public sealed class AppDomain : MarshalByRefObject {
+#else
+       public sealed class AppDomain : MarshalByRefObject, _AppDomain, IEvidenceFactory {
+#endif
+        #pragma warning disable 169
+        #region Sync with object-internals.h
                IntPtr _mono_app_domain;
+               #endregion
+        #pragma warning restore 169
                static string _process_guid;
 
                [ThreadStatic]
@@ -71,6 +79,9 @@ namespace System {
                [ThreadStatic]
                static Hashtable assembly_resolve_in_progress;
 
+               [ThreadStatic]
+               static Hashtable assembly_resolve_in_progress_refonly;
+#if !MOONLIGHT
                // CAS
                private Evidence _evidence;
                private PermissionSet _granted;
@@ -80,6 +91,8 @@ namespace System {
 
                [ThreadStatic]
                private static IPrincipal _principal;
+#endif
+               static AppDomain default_domain;
 
                private AppDomain ()
                {
@@ -88,6 +101,9 @@ namespace System {
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                private extern AppDomainSetup getSetup ();
 
+#if NET_2_1
+               internal
+#endif
                AppDomainSetup SetupInformationNoCopy {
                        get { return getSetup (); }
                }
@@ -99,6 +115,13 @@ namespace System {
                        }
                }
 
+#if !NET_2_1
+               [MonoTODO]
+               public ApplicationTrust ApplicationTrust {
+                       get { throw new NotImplementedException (); }
+               }
+#endif
+#if !MOONLIGHT
                public string BaseDirectory {
                        get {
                                string path = SetupInformationNoCopy.ApplicationBase;
@@ -141,6 +164,7 @@ namespace System {
                                return (SetupInformationNoCopy.ShadowCopyFiles == "true");
                        }
                }
+#endif
 
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                private extern string getFriendlyName ();
@@ -150,7 +174,7 @@ namespace System {
                                return getFriendlyName ();
                        }
                }
-
+#if !MOONLIGHT
                public Evidence Evidence {
                        get {
                                // if the host (runtime) hasn't provided it's own evidence...
@@ -158,12 +182,18 @@ namespace System {
                                        // ... we will provide our own
                                        lock (this) {
                                                // the executed assembly from the "default" appdomain
-                                               // or null if we're not in the default appdomain
+                                               // or null if we're not in the default appdomain or
+                                               // if there is no entry assembly (embedded mono)
                                                Assembly a = Assembly.GetEntryAssembly ();
-                                               if (a == null)
-                                                       _evidence = AppDomain.DefaultDomain.Evidence;
-                                               else
+                                               if (a == null) {
+                                                       if (this == DefaultDomain)
+                                                               // mono is embedded
+                                                               return new Evidence ();
+                                                       else
+                                                               _evidence = AppDomain.DefaultDomain.Evidence;
+                                               } else {
                                                        _evidence = Evidence.GetDefaultHostEvidence (a);
+                                               }
                                        }
                                }
                                return new Evidence (_evidence);        // return a copy
@@ -192,7 +222,7 @@ namespace System {
                internal PermissionSet GrantedPermissionSet {
                        get { return _granted; }
                }
-
+#endif
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                private static extern AppDomain getCurDomain ();
                
@@ -207,13 +237,20 @@ namespace System {
 
                internal static AppDomain DefaultDomain {
                        get {
-                               return getRootDomain ();
+                               if (default_domain == null) {
+                                       AppDomain rd = getRootDomain ();
+                                       if (rd == CurrentDomain)
+                                               default_domain = rd;
+                                       else
+                                               default_domain = (AppDomain) RemotingServices.GetDomainProxy (rd);
+                               }
+                               return default_domain;
                        }
                }
 
-#if NET_2_0
-               [Obsolete ("")]
-#endif
+#if !MOONLIGHT
+
+               [Obsolete ("AppDomain.AppendPrivatePath has been deprecated. Please investigate the use of AppDomainSetup.PrivateBinPath instead.")]
                [SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
                public void AppendPrivatePath (string path)
                {
@@ -235,31 +272,30 @@ namespace System {
                        setup.PrivateBinPath = pp + path;
                }
 
-#if NET_2_0
-               [Obsolete ("")]
-#endif
+               [Obsolete ("AppDomain.ClearPrivatePath has been deprecated. Please investigate the use of AppDomainSetup.PrivateBinPath instead.")]
                [SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
                public void ClearPrivatePath ()
                {
                        SetupInformationNoCopy.PrivateBinPath = String.Empty;
                }
 
+               [Obsolete ("Use AppDomainSetup.ShadowCopyDirectories")]
                [SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
                public void ClearShadowCopyPath ()
                {
                        SetupInformationNoCopy.ShadowCopyDirectories = String.Empty;
                }
 
+#if !NET_2_1
                public ObjectHandle CreateComInstanceFrom (string assemblyName, string typeName)
                {
                        return Activator.CreateComInstanceFrom (assemblyName, typeName);
                }
 
-#if NET_1_1
-               public ObjectHandle CreateComInstanceFrom (string assemblyName, string typeName,
+               public ObjectHandle CreateComInstanceFrom (string assemblyFile, string typeName,
                        byte [] hashValue, AssemblyHashAlgorithm hashAlgorithm)
                {
-                       return Activator.CreateComInstanceFrom (assemblyName, typeName, hashValue ,hashAlgorithm);
+                       return Activator.CreateComInstanceFrom (assemblyFile, typeName, hashValue ,hashAlgorithm);
                }
 #endif
 
@@ -279,6 +315,9 @@ namespace System {
                        return Activator.CreateInstance (assemblyName, typeName, activationAttributes);
                }
 
+#if NET_4_0
+               [Obsolete ("Use an overload that does not take an Evidence parameter")]
+#endif
                public ObjectHandle CreateInstance (string assemblyName, string typeName, bool ignoreCase, BindingFlags bindingAttr,
                                                    Binder binder, object[] args, CultureInfo culture, object[] activationAttributes,
                                                    Evidence securityAttributes)
@@ -302,6 +341,9 @@ namespace System {
                        return (oh != null) ? oh.Unwrap () : null;
                }
 
+#if NET_4_0
+               [Obsolete ("Use an overload that does not take an Evidence parameter")]
+#endif
                public object CreateInstanceAndUnwrap (string assemblyName, string typeName, bool ignoreCase,
                                                       BindingFlags bindingAttr, Binder binder, object[] args, CultureInfo culture,
                                                       object[] activationAttributes, Evidence securityAttributes)
@@ -311,30 +353,74 @@ namespace System {
                        return (oh != null) ? oh.Unwrap () : null;
                }
 
-               public ObjectHandle CreateInstanceFrom (string assemblyName, string typeName)
+#if NET_4_0
+               public ObjectHandle CreateInstance (string assemblyName, string typeName, bool ignoreCase, BindingFlags bindingAttr,
+                                                   Binder binder, object[] args, CultureInfo culture, object[] activationAttributes)
                {
                        if (assemblyName == null)
                                throw new ArgumentNullException ("assemblyName");
 
-                       return Activator.CreateInstanceFrom (assemblyName, typeName);
+                       return Activator.CreateInstance (assemblyName, typeName, ignoreCase, bindingAttr, binder, args,
+                               culture, activationAttributes, null);
+               }
+               public object CreateInstanceAndUnwrap (string assemblyName, string typeName, bool ignoreCase,
+                                                      BindingFlags bindingAttr, Binder binder, object[] args, CultureInfo culture,
+                                                      object[] activationAttributes)
+               {
+                       ObjectHandle oh = CreateInstance (assemblyName, typeName, ignoreCase, bindingAttr, binder, args,
+                               culture, activationAttributes);
+                       return (oh != null) ? oh.Unwrap () : null;
                }
 
-               public ObjectHandle CreateInstanceFrom (string assemblyName, string typeName, object[] activationAttributes)
+               public ObjectHandle CreateInstanceFrom (string assemblyFile, string typeName, bool ignoreCase,
+                                                       BindingFlags bindingAttr, Binder binder, object[] args, CultureInfo culture,
+                                                       object[] activationAttributes)
                {
-                       if (assemblyName == null)
-                               throw new ArgumentNullException ("assemblyName");
+                       if (assemblyFile == null)
+                               throw new ArgumentNullException ("assemblyFile");
+
+                       return Activator.CreateInstanceFrom (assemblyFile, typeName, ignoreCase, bindingAttr, binder, args,
+                                                            culture, activationAttributes, null);
+               }
+
+               public object CreateInstanceFromAndUnwrap (string assemblyName, string typeName, bool ignoreCase,
+                                                          BindingFlags bindingAttr, Binder binder, object[] args,
+                                                          CultureInfo culture, object[] activationAttributes)
+               {
+                       ObjectHandle oh = CreateInstanceFrom (assemblyName, typeName, ignoreCase, bindingAttr, binder, args,
+                               culture, activationAttributes);
+
+                       return (oh != null) ? oh.Unwrap () : null;
+               }
+#endif
 
-                       return Activator.CreateInstanceFrom (assemblyName, typeName, activationAttributes);
+               public ObjectHandle CreateInstanceFrom (string assemblyFile, string typeName)
+               {
+                       if (assemblyFile == null)
+                               throw new ArgumentNullException ("assemblyFile");
+
+                       return Activator.CreateInstanceFrom (assemblyFile, typeName);
+               }
+
+               public ObjectHandle CreateInstanceFrom (string assemblyFile, string typeName, object[] activationAttributes)
+               {
+                       if (assemblyFile == null)
+                               throw new ArgumentNullException ("assemblyFile");
+
+                       return Activator.CreateInstanceFrom (assemblyFile, typeName, activationAttributes);
                }
 
-               public ObjectHandle CreateInstanceFrom (string assemblyName, string typeName, bool ignoreCase,
+#if NET_4_0
+               [Obsolete ("Use an overload that does not take an Evidence parameter")]
+#endif
+               public ObjectHandle CreateInstanceFrom (string assemblyFile, string typeName, bool ignoreCase,
                                                        BindingFlags bindingAttr, Binder binder, object[] args, CultureInfo culture,
                                                        object[] activationAttributes, Evidence securityAttributes)
                {
-                       if (assemblyName == null)
-                               throw new ArgumentNullException ("assemblyName");
+                       if (assemblyFile == null)
+                               throw new ArgumentNullException ("assemblyFile");
 
-                       return Activator.CreateInstanceFrom (assemblyName, typeName, ignoreCase, bindingAttr, binder, args,
+                       return Activator.CreateInstanceFrom (assemblyFile, typeName, ignoreCase, bindingAttr, binder, args,
                                                             culture, activationAttributes, securityAttributes);
                }
 
@@ -350,6 +436,9 @@ namespace System {
                        return (oh != null) ? oh.Unwrap () : null;
                }
 
+#if NET_4_0
+               [Obsolete ("Use an overload that does not take an Evidence parameter")]
+#endif
                public object CreateInstanceFromAndUnwrap (string assemblyName, string typeName, bool ignoreCase,
                                                           BindingFlags bindingAttr, Binder binder, object[] args,
                                                           CultureInfo culture, object[] activationAttributes,
@@ -361,11 +450,16 @@ namespace System {
                        return (oh != null) ? oh.Unwrap () : null;
                }
 
+#endif // !NET_2_1
+
                public AssemblyBuilder DefineDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access)
                {
                        return DefineDynamicAssembly (name, access, null, null, null, null, null, false);
                }
 
+#if NET_4_0
+               [Obsolete ("Declarative security for assembly level is no longer enforced")]
+#endif
                public AssemblyBuilder DefineDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access, Evidence evidence)
                {
                        return DefineDynamicAssembly (name, access, null, evidence, null, null, null, false);
@@ -376,12 +470,18 @@ namespace System {
                        return DefineDynamicAssembly (name, access, dir, null, null, null, null, false);
                }
 
+#if NET_4_0
+               [Obsolete ("Declarative security for assembly level is no longer enforced")]
+#endif
                public AssemblyBuilder DefineDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access, string dir,
                                                              Evidence evidence)
                {
                        return DefineDynamicAssembly (name, access, dir, evidence, null, null, null, false);
                }
 
+#if NET_4_0
+               [Obsolete ("Declarative security for assembly level is no longer enforced")]
+#endif
                public AssemblyBuilder DefineDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access,
                                                              PermissionSet requiredPermissions,
                                                              PermissionSet optionalPermissions,
@@ -391,6 +491,9 @@ namespace System {
                                refusedPermissions, false);
                }
 
+#if NET_4_0
+               [Obsolete ("Declarative security for assembly level is no longer enforced")]
+#endif
                public AssemblyBuilder DefineDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access, Evidence evidence,
                                                              PermissionSet requiredPermissions,
                                                              PermissionSet optionalPermissions,
@@ -400,6 +503,9 @@ namespace System {
                                refusedPermissions, false);
                }
 
+#if NET_4_0
+               [Obsolete ("Declarative security for assembly level is no longer enforced")]
+#endif
                public AssemblyBuilder DefineDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access, string dir,
                                                              PermissionSet requiredPermissions,
                                                              PermissionSet optionalPermissions,
@@ -409,6 +515,9 @@ namespace System {
                                refusedPermissions, false);
                }
 
+#if NET_4_0
+               [Obsolete ("Declarative security for assembly level is no longer enforced")]
+#endif
                public AssemblyBuilder DefineDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access, string dir,
                                                              Evidence evidence,
                                                              PermissionSet requiredPermissions,
@@ -419,12 +528,19 @@ namespace System {
                                refusedPermissions, false);
                }
 
+#if NET_4_0
+               [Obsolete ("Declarative security for assembly level is no longer enforced")]
+#endif
                public AssemblyBuilder DefineDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access, string dir,
                                                              Evidence evidence,
                                                              PermissionSet requiredPermissions,
                                                              PermissionSet optionalPermissions,
                                                              PermissionSet refusedPermissions, bool isSynchronized)
                {
+                       if (name == null)
+                               throw new ArgumentNullException ("name");
+                       ValidateAssemblyName (name.Name);
+
                        // FIXME: examine all other parameters
                        
                        AssemblyBuilder ab = new AssemblyBuilder (name, dir, access, false);
@@ -432,35 +548,99 @@ namespace System {
                        return ab;
                }
 
+               // NET 3.5 method
+#if NET_4_0
+               [Obsolete ("Declarative security for assembly level is no longer enforced")]
+#endif
+               public AssemblyBuilder DefineDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access, string dir,
+                                                             Evidence evidence,
+                                                             PermissionSet requiredPermissions,
+                                                             PermissionSet optionalPermissions,
+                                                             PermissionSet refusedPermissions, bool isSynchronized, IEnumerable<CustomAttributeBuilder> assemblyAttributes)
+               {
+                       AssemblyBuilder ab = DefineDynamicAssembly (name, access, dir, evidence, requiredPermissions, optionalPermissions, refusedPermissions, isSynchronized);
+                       if (assemblyAttributes != null)
+                               foreach (CustomAttributeBuilder cb in assemblyAttributes) {
+                                       ab.SetCustomAttribute (cb);
+                               }
+                       return ab;
+               }
+
+               // NET 3.5 method
+               public AssemblyBuilder DefineDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access, IEnumerable<CustomAttributeBuilder> assemblyAttributes) {
+                       return DefineDynamicAssembly (name, access, null, null, null, null, null, false, assemblyAttributes);
+               }
+
                internal AssemblyBuilder DefineInternalDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access)
                {
                        return new AssemblyBuilder (name, null, access, true);
                }
 
-               public void DoCallBack (CrossAppDomainDelegate theDelegate)
+               //
+               // AppDomain.DoCallBack works because AppDomain is a MarshalByRefObject
+               // so, when you call AppDomain.DoCallBack, that's a remote call
+               //
+               public void DoCallBack (CrossAppDomainDelegate callBackDelegate)
                {
-                       if (theDelegate != null)
-                               theDelegate ();
+                       if (callBackDelegate != null)
+                               callBackDelegate ();
                }
 
                public int ExecuteAssembly (string assemblyFile)
                {
-                       return ExecuteAssembly (assemblyFile, null, null);
+                       return ExecuteAssembly (assemblyFile, (Evidence)null, null);
                }
 
+#if NET_4_0
+               [Obsolete ("Use an overload that does not take an Evidence parameter")]
+#endif
                public int ExecuteAssembly (string assemblyFile, Evidence assemblySecurity)
                {
                        return ExecuteAssembly (assemblyFile, assemblySecurity, null);
                }
 
-               [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               public extern int ExecuteAssembly (string assemblyFile, Evidence assemblySecurity, string[] args);
+#if NET_4_0
+               [Obsolete ("Use an overload that does not take an Evidence parameter")]
+#endif
+               public int ExecuteAssembly (string assemblyFile, Evidence assemblySecurity, string[] args)
+               {
+                       Assembly a = Assembly.LoadFrom (assemblyFile, assemblySecurity);
+                       return ExecuteAssemblyInternal (a, args);
+               }
 
-               [MonoTODO ("No support for ExecuteAssembly")]
+#if NET_4_0
+               [Obsolete ("Use an overload that does not take an Evidence parameter")]
+#endif
                public int ExecuteAssembly (string assemblyFile, Evidence assemblySecurity, string[] args, byte[] hashValue, AssemblyHashAlgorithm hashAlgorithm)
                {
-                       throw new NotImplementedException ();
+                       Assembly a = Assembly.LoadFrom (assemblyFile, assemblySecurity, hashValue, hashAlgorithm);
+                       return ExecuteAssemblyInternal (a, args);
+               }
+
+
+#if NET_4_0
+               public int ExecuteAssembly (string assemblyFile, string[] args)
+               {
+                       Assembly a = Assembly.LoadFrom (assemblyFile, null);
+                       return ExecuteAssemblyInternal (a, args);
+               }
+
+               public int ExecuteAssembly (string assemblyFile, string[] args, byte[] hashValue, AssemblyHashAlgorithm hashAlgorithm)
+               {
+                       Assembly a = Assembly.LoadFrom (assemblyFile, null, hashValue, hashAlgorithm);
+                       return ExecuteAssemblyInternal (a, args);
+               }
+#endif
+
+               int ExecuteAssemblyInternal (Assembly a, string[] args)
+               {
+                       if (a.EntryPoint == null)
+                               throw new MissingMethodException ("Entry point not found in assembly '" + a.FullName + "'.");
+                       return ExecuteAssembly (a, args);
                }
+
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               private extern int ExecuteAssembly (Assembly a, string[] args);
                
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                private extern Assembly [] GetAssemblies (bool refOnly);
@@ -491,6 +671,20 @@ namespace System {
                        return Load (assemblyRef, null);
                }
 
+               internal Assembly LoadSatellite (AssemblyName assemblyRef, bool throwOnError)
+               {
+                       if (assemblyRef == null)
+                               throw new ArgumentNullException ("assemblyRef");
+
+                       Assembly result = LoadAssembly (assemblyRef.FullName, null, false);
+                       if (result == null && throwOnError)
+                               throw new FileNotFoundException (null, assemblyRef.Name);
+                       return result;
+               }
+
+#if NET_4_0
+               [Obsolete ("Use an overload that does not take an Evidence parameter")]
+#endif
                public Assembly Load (AssemblyName assemblyRef, Evidence assemblySecurity)
                {
                        if (assemblyRef == null)
@@ -503,17 +697,53 @@ namespace System {
                                        throw new ArgumentException (Locale.GetText ("assemblyRef.Name cannot be empty."), "assemblyRef");
                        }
 
-                       return LoadAssembly (assemblyRef.FullName, assemblySecurity, false);
+                       Assembly assembly = LoadAssembly (assemblyRef.FullName, assemblySecurity, false);
+                       if (assembly != null)
+                               return assembly;
+
+                       if (assemblyRef.CodeBase == null)
+                               throw new FileNotFoundException (null, assemblyRef.Name);
+
+                       string cb = assemblyRef.CodeBase;
+                       if (cb.ToLower (CultureInfo.InvariantCulture).StartsWith ("file://"))
+                               cb = new Mono.Security.Uri (cb).LocalPath;
+
+                       try {
+                               assembly = Assembly.LoadFrom (cb, assemblySecurity);
+                       } catch {
+                               throw new FileNotFoundException (null, assemblyRef.Name);
+                       }
+                       AssemblyName aname = assembly.GetName ();
+                       // Name, version, culture, publickeytoken. Anything else?
+                       if (assemblyRef.Name != aname.Name)
+                               throw new FileNotFoundException (null, assemblyRef.Name);
+
+                       if (assemblyRef.Version != new Version () && assemblyRef.Version != aname.Version)
+                               throw new FileNotFoundException (null, assemblyRef.Name);
+
+                       if (assemblyRef.CultureInfo != null && assemblyRef.CultureInfo.Equals (aname))
+                               throw new FileNotFoundException (null, assemblyRef.Name);
+
+                       byte [] pt = assemblyRef.GetPublicKeyToken ();
+                       if (pt != null) {
+                               byte [] loaded_pt = aname.GetPublicKeyToken ();
+                               if (loaded_pt == null || (pt.Length != loaded_pt.Length))
+                                       throw new FileNotFoundException (null, assemblyRef.Name);
+                               for (int i = pt.Length - 1; i >= 0; i--)
+                                       if (loaded_pt [i] != pt [i])
+                                               throw new FileNotFoundException (null, assemblyRef.Name);
+                       }
+                       return assembly;
                }
 
                public Assembly Load (string assemblyString)
                {
-                       if (assemblyString == null)
-                               throw new ArgumentNullException ("assemblyString");
-
-                       return LoadAssembly (assemblyString, null, false);
+                       return Load (assemblyString, null, false);
                }
 
+#if NET_4_0
+               [Obsolete ("Use an overload that does not take an Evidence parameter")]
+#endif
                public Assembly Load (string assemblyString, Evidence assemblySecurity)
                {
                        return Load (assemblyString, assemblySecurity, false);
@@ -523,8 +753,14 @@ namespace System {
                {
                        if (assemblyString == null)
                                throw new ArgumentNullException ("assemblyString");
+                               
+                       if (assemblyString.Length == 0)
+                               throw new ArgumentException ("assemblyString cannot have zero length");
 
-                       return LoadAssembly (assemblyString, assemblySecurity, refonly);
+                       Assembly assembly = LoadAssembly (assemblyString, assemblySecurity, refonly);
+                       if (assembly == null)
+                               throw new FileNotFoundException (null, assemblyString);
+                       return assembly;
                }
 
                public Assembly Load (byte[] rawAssembly)
@@ -540,6 +776,9 @@ namespace System {
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                internal extern Assembly LoadAssemblyRaw (byte[] rawAssembly, byte[] rawSymbolStore, Evidence securityEvidence, bool refonly);
 
+#if NET_4_0
+               [Obsolete ("Use an overload that does not take an Evidence parameter")]
+#endif
                public Assembly Load (byte[] rawAssembly, byte[] rawSymbolStore, Evidence securityEvidence)
                {
                        return Load (rawAssembly, rawSymbolStore, securityEvidence, false);
@@ -549,12 +788,15 @@ namespace System {
                {
                        if (rawAssembly == null)
                                throw new ArgumentNullException ("rawAssembly");
-                               
+
                        Assembly assembly = LoadAssemblyRaw (rawAssembly, rawSymbolStore, securityEvidence, refonly);
                        assembly.FromByteArray = true;
                        return assembly;
                }
-
+#if !MOONLIGHT
+#if NET_4_0
+               [Obsolete ("AppDomain policy levels are obsolete")]
+#endif
                [SecurityPermission (SecurityAction.Demand, ControlPolicy = true)]
                public void SetAppDomainPolicy (PolicyLevel domainPolicy)
                {
@@ -571,6 +813,7 @@ namespace System {
                        _granted = ps.PermissionSet;
                }
 
+               [Obsolete ("Use AppDomainSetup.SetCachePath")]
                [SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
                public void SetCachePath (string path)
                {
@@ -587,12 +830,14 @@ namespace System {
                        _principal = null;
                }
 
+               [Obsolete ("Use AppDomainSetup.ShadowCopyFiles")]
                [SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
                public void SetShadowCopyFiles()
                {
                        SetupInformationNoCopy.ShadowCopyFiles = "true";
                }
 
+               [Obsolete ("Use AppDomainSetup.ShadowCopyDirectories")]
                [SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
                public void SetShadowCopyPath (string path)
                {
@@ -611,7 +856,7 @@ namespace System {
 
                        _principal = principal;
                }
-
+#endif
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                private static extern AppDomain InternalSetDomainByID (int domain_id);
  
@@ -654,10 +899,14 @@ namespace System {
                        bool pushed = false;
 
                        try {
+                               Exception exc;
                                InternalPushDomainRef (domain);
                                pushed = true;
                                InternalSetDomain (domain);
-                               return ((MonoMethod) method).InternalInvoke (obj, args);
+                               object o = ((MonoMethod) method).InternalInvoke (obj, args, out exc);
+                               if (exc != null)
+                                       throw exc;
+                               return o;
                        }
                        finally {
                                InternalSetDomain (current);
@@ -672,10 +921,14 @@ namespace System {
                        bool pushed = false;
 
                        try {
+                               Exception exc;
                                InternalPushDomainRefByID (domain_id);
                                pushed = true;
                                InternalSetDomainByID (domain_id);
-                               return ((MonoMethod) method).InternalInvoke (obj, args);
+                               object o = ((MonoMethod) method).InternalInvoke (obj, args, out exc);
+                               if (exc != null)
+                                       throw exc;
+                               return o;
                        }
                        finally {
                                InternalSetDomain (current);
@@ -692,6 +945,8 @@ namespace System {
                        return _process_guid;
                }
 
+#if !MOONLIGHT
+
                public static AppDomain CreateDomain (string friendlyName)
                {
                        return CreateDomain (friendlyName, null, null);
@@ -705,7 +960,7 @@ namespace System {
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                private static extern AppDomain createDomain (string friendlyName, AppDomainSetup info);
 
-               [MonoTODO ("Currently it does not allow the setup in the other domain")]
+               [MonoLimitationAttribute ("Currently it does not allow the setup in the other domain")]
                [SecurityPermission (SecurityAction.Demand, ControlAppDomain = true)]
                public static AppDomain CreateDomain (string friendlyName, Evidence securityInfo, AppDomainSetup info)
                {
@@ -735,6 +990,15 @@ namespace System {
                        } else if (info.ConfigurationFile == null)
                                info.ConfigurationFile = "[I don't have a config file]";
 
+#if !NET_2_1
+                       if (info.AppDomainInitializer != null) {
+                               if (!info.AppDomainInitializer.Method.IsStatic)
+                                       throw new ArgumentException ("Non-static methods cannot be invoked as an appdomain initializer");
+                       }
+#endif
+
+                       info.SerializeNonPrimitives ();
+
                        AppDomain ad = (AppDomain) RemotingServices.GetDomainProxy (createDomain (friendlyName, info));
                        if (securityInfo == null) {
                                // get default domain's Evidence (unless we're are the default!)
@@ -746,11 +1010,77 @@ namespace System {
                        else
                                ad._evidence = new Evidence (securityInfo);     // copy
 
+#if !NET_2_1
+                       if (info.AppDomainInitializer != null) {
+                               Loader loader = new Loader (
+                                       info.AppDomainInitializer.Method.DeclaringType.Assembly.Location);
+                               ad.DoCallBack (loader.Load);
+
+                               Initializer initializer = new Initializer (
+                                       info.AppDomainInitializer,
+                                       info.AppDomainInitializerArguments);
+                               ad.DoCallBack (initializer.Initialize);
+                       }
+#endif
+
                        return ad;
                }
 
+#if !NET_2_1
+               [Serializable]
+               class Loader {
+
+                       string assembly;
+
+                       public Loader (string assembly)
+                       {
+                               this.assembly = assembly;
+                       }
+
+                       public void Load ()
+                       {
+                               Assembly.LoadFrom (assembly);
+                       }
+               }
+
+               [Serializable]
+               class Initializer {
+
+                       AppDomainInitializer initializer;
+                       string [] arguments;
+
+                       public Initializer (AppDomainInitializer initializer, string [] arguments)
+                       {
+                               this.initializer = initializer;
+                               this.arguments = arguments;
+                       }
+
+                       public void Initialize ()
+                       {
+                               initializer (arguments);
+                       }
+               }
+#endif
+
                public static AppDomain CreateDomain (string friendlyName, Evidence securityInfo,string appBasePath,
                                                      string appRelativeSearchPath, bool shadowCopyFiles)
+               {
+                       return CreateDomain (friendlyName, securityInfo, CreateDomainSetup (appBasePath, appRelativeSearchPath, shadowCopyFiles));
+               }
+               
+#if !NET_2_1
+               public static AppDomain CreateDomain (string friendlyName, Evidence securityInfo, AppDomainSetup info,
+                                                     PermissionSet grantSet, params StrongName [] fullTrustAssemblies)
+               {
+                       if (info == null)
+                               throw new ArgumentNullException ("info");
+
+                       info.ApplicationTrust = new ApplicationTrust (grantSet, fullTrustAssemblies ?? new StrongName [0]);
+                       return CreateDomain (friendlyName, securityInfo, info);         
+               }
+#endif
+
+               static AppDomainSetup CreateDomainSetup (string appBasePath, string appRelativeSearchPath, bool shadowCopyFiles)
                {
                        AppDomainSetup info = new AppDomainSetup ();
 
@@ -762,8 +1092,9 @@ namespace System {
                        else
                                info.ShadowCopyFiles = "false";
 
-                       return CreateDomain (friendlyName, securityInfo, info);
+                       return info;
                }
+#endif // !NET_2_1
 
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                private static extern bool InternalIsFinalizingForUnload (int domain_id);
@@ -784,9 +1115,7 @@ namespace System {
                }
 
                [SecurityPermission (SecurityAction.Demand, ControlAppDomain = true)]
-#if NET_2_0
                [ReliabilityContractAttribute (Consistency.MayCorruptAppDomain, Cer.MayFail)]
-#endif
                public static void Unload (AppDomain domain)
                {
                        if (domain == null)
@@ -799,15 +1128,26 @@ namespace System {
                [SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
                public extern void SetData (string name, object data);
 
+               [MonoLimitation ("The permission field is ignored")]
+               public void SetData (string name, object data, IPermission permission)
+               {
+                       SetData (name, data);
+               }
+
+#if !NET_2_1
+               [Obsolete ("Use AppDomainSetup.DynamicBase")]
                [SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
                public void SetDynamicBase (string path)
                {
                        SetupInformationNoCopy.DynamicBase = path;
                }
+#endif // !NET_2_1
 
-#if NET_2_0
-               [Obsolete ("")]
-#endif
+               [Obsolete ("AppDomain.GetCurrentThreadId has been deprecated"
+                       + " because it does not provide a stable Id when managed"
+                       + " threads are running on fibers (aka lightweight"
+                       + " threads). To get a stable identifier for a managed"
+                       + " thread, use the ManagedThreadId property on Thread.'")]
                public static int GetCurrentThreadId ()
                {
                        return Thread.CurrentThreadId;
@@ -815,10 +1155,50 @@ namespace System {
 
                public override string ToString ()
                {
+#if !MOONLIGHT
                        return getFriendlyName ();
+#else
+                       StringBuilder sb = new StringBuilder ("Name:");
+                       sb.AppendLine (FriendlyName);
+                       sb.AppendLine ("There are no context policies.");
+                       return sb.ToString ();
+#endif
+               }
+
+               private static void ValidateAssemblyName (string name)
+               {
+                       if (name == null || name.Length == 0)
+                               throw new ArgumentException ("The Name of " +
+                                       "AssemblyName cannot be null or a " +
+                                       "zero-length string.");
+
+                       bool isValid = true;
+
+                       for (int i = 0; i < name.Length; i++) {
+                               char c = name [i];
+
+                               // do not allow leading whitespace
+                               if (i == 0 && char.IsWhiteSpace (c)) {
+                                       isValid = false;
+                                       break;
+                               }
+
+                               // do not allow /,\ or : in name
+                               if (c == '/' || c == '\\' || c == ':') {
+                                       isValid = false;
+                                       break;
+                               }
+                       }
+
+                       if (!isValid)
+                               throw new ArgumentException ("The Name of " +
+                                       "AssemblyName cannot start with " +
+                                       "whitespace, or contain '/', '\\' " +
+                                       " or ':'.");
                }
 
                // The following methods are called from the runtime. Don't change signatures.
+#pragma warning disable 169            
                private void DoAssemblyLoad (Assembly assembly)
                {
                        if (AssemblyLoad == null)
@@ -829,37 +1209,40 @@ namespace System {
 
                private Assembly DoAssemblyResolve (string name, bool refonly)
                {
-#if NET_2_0
-                       if (refonly && ReflectionOnlyAssemblyResolve == null)
-                               return null;
+                       ResolveEventHandler del;
+#if !NET_2_1
+                       if (refonly)
+                               del = ReflectionOnlyAssemblyResolve;
+                       else
+                               del = AssemblyResolve;
+#else
+                       del = AssemblyResolve;
 #endif
-                       if (AssemblyResolve == null)
+                       if (del == null)
                                return null;
                        
                        /* Prevent infinite recursion */
-                       Hashtable ht = assembly_resolve_in_progress;
-                       if (ht == null) {
-                               ht = new Hashtable ();
-                               assembly_resolve_in_progress = ht;
+                       Hashtable ht;
+                       if (refonly) {
+                               ht = assembly_resolve_in_progress_refonly;
+                               if (ht == null) {
+                                       ht = new Hashtable ();
+                                       assembly_resolve_in_progress_refonly = ht;
+                               }
+                       } else {
+                               ht = assembly_resolve_in_progress;
+                               if (ht == null) {
+                                       ht = new Hashtable ();
+                                       assembly_resolve_in_progress = ht;
+                               }
                        }
 
-                       Assembly ass = (Assembly) ht [name];
-#if NET_2_0
-                       if (ass != null && (ass.ReflectionOnly == refonly))
-                               return null;
-#else
-                       if (ass != null)
+                       string s = (string) ht [name];
+                       if (s != null)
                                return null;
-#endif
                        ht [name] = name;
                        try {
-                               
-#if NET_2_0
-                               Delegate [] invocation_list = refonly ? ReflectionOnlyAssemblyResolve.GetInvocationList () : 
-                                       AssemblyResolve.GetInvocationList ();
-#else
-                               Delegate [] invocation_list = AssemblyResolve.GetInvocationList ();
-#endif
+                               Delegate[] invocation_list = del.GetInvocationList ();
 
                                foreach (Delegate eh in invocation_list) {
                                        ResolveEventHandler handler = (ResolveEventHandler) eh;
@@ -918,12 +1301,13 @@ namespace System {
                                DomainUnload(this, null);
                }
 
+#if !NET_2_1
                internal byte[] GetMarshalledDomainObjRef ()
                {
                        ObjRef oref = RemotingServices.Marshal (AppDomain.CurrentDomain, null, typeof (AppDomain));
                        return CADSerializer.SerializeObject (oref).GetBuffer();
                }
-
+#endif
                internal void ProcessMessageInDomain (byte[] arrRequest, CADMethodCallMessage cadMsg,
                                                      out byte[] arrResponse, out CADMethodReturnMessage cadMrm)
                {
@@ -944,26 +1328,10 @@ namespace System {
                                arrResponse = null;
                }
 
+#pragma warning restore 169
+
                // End of methods called from the runtime
                
-#if BOOTSTRAP_WITH_OLDLIB
-               // older MCS/corlib returns:
-               // _AppDomain.cs(138) error CS0592: Attribute 'SecurityPermission' is not valid on this declaration type.
-               // It is valid on 'assembly' 'class' 'constructor' 'method' 'struct'  declarations only.
-               public event AssemblyLoadEventHandler AssemblyLoad;
-
-               public event ResolveEventHandler AssemblyResolve;
-
-               public event EventHandler DomainUnload;
-
-               public event EventHandler ProcessExit;
-
-               public event ResolveEventHandler ResourceResolve;
-
-               public event ResolveEventHandler TypeResolve;
-
-               public event UnhandledExceptionEventHandler UnhandledException;
-#else
                [method: SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
                public event AssemblyLoadEventHandler AssemblyLoad;
 
@@ -984,22 +1352,31 @@ namespace System {
 
                [method: SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
                public event UnhandledExceptionEventHandler UnhandledException;
+
+#if NET_4_0 || BOOTSTRAP_NET_4_0
+               [MonoTODO]
+               public bool IsHomogenous {
+                       get { return true; }
+               }
 #endif
 
-               /* Avoid warnings for events used only by the runtime */
-               private void DummyUse () {
-                       ProcessExit += (EventHandler)null;
-                       ResourceResolve += (ResolveEventHandler)null;
-                       UnhandledException += (UnhandledExceptionEventHandler)null;
+        #pragma warning disable 649
+               private AppDomainManager _domain_manager;
+        #pragma warning restore 649
+
+               // default is null
+               public AppDomainManager DomainManager {
+                       get { return _domain_manager; }
                }
 
-#if NET_2_0
+#if (!MOONLIGHT)
 
                public event ResolveEventHandler ReflectionOnlyAssemblyResolve;
-               
+
+        #pragma warning disable 649
                private ActivationContext _activation;
                private ApplicationIdentity _applicationIdentity;
-               private AppDomainManager _domain_manager;
+        #pragma warning restore 649
 
                // properties
 
@@ -1011,11 +1388,6 @@ namespace System {
                        get { return _applicationIdentity; }
                }
 
-               // default is null
-               public AppDomainManager DomainManager {
-                       get { return _domain_manager; }
-               }
-
                public int Id {
                        [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
                        get { return getDomainID (); }
@@ -1036,43 +1408,65 @@ namespace System {
 
                // static methods
 
-               [MonoTODO ("add support for new delegate")]
                public static AppDomain CreateDomain (string friendlyName, Evidence securityInfo, string appBasePath,
-                       string appRelativeSearchPath, bool shadowCopy, AppDomainInitializer adInit, string[] adInitArgs)
+                       string appRelativeSearchPath, bool shadowCopyFiles, AppDomainInitializer adInit, string[] adInitArgs)
                {
-                       return CreateDomain (friendlyName, securityInfo, appBasePath, appRelativeSearchPath, shadowCopy);
+                       AppDomainSetup info = CreateDomainSetup (appBasePath, appRelativeSearchPath, shadowCopyFiles);
+
+                       info.AppDomainInitializerArguments = adInitArgs;
+                       info.AppDomainInitializer = adInit;
+
+                       return CreateDomain (friendlyName, securityInfo, info);
                }
 
-               [MonoTODO ("resolve assemblyName to location")]
                public int ExecuteAssemblyByName (string assemblyName)
                {
-                       return ExecuteAssemblyByName (assemblyName, null, null);
+                       return ExecuteAssemblyByName (assemblyName, (Evidence)null, null);
                }
 
-               [MonoTODO ("resolve assemblyName to location")]
+#if NET_4_0
+               [Obsolete ("Use an overload that does not take an Evidence parameter")]
+#endif
                public int ExecuteAssemblyByName (string assemblyName, Evidence assemblySecurity)
                {
                        return ExecuteAssemblyByName (assemblyName, assemblySecurity, null);
                }
 
-               [MonoTODO ("resolve assemblyName to location")]
-               public int ExecuteAssemblyByName (string assemblyName, Evidence assemblySecurity, string[] args)
+#if NET_4_0
+               [Obsolete ("Use an overload that does not take an Evidence parameter")]
+#endif
+               public int ExecuteAssemblyByName (string assemblyName, Evidence assemblySecurity, params string[] args)
                {
-                       if (assemblyName == null)
-                               throw new ArgumentNullException ("assemblyName");
+                       Assembly a = Assembly.Load (assemblyName, assemblySecurity);
 
-                       AssemblyName an = new AssemblyName (assemblyName);
-                       return ExecuteAssemblyByName (an, assemblySecurity, args);
+                       return ExecuteAssemblyInternal (a, args);
                }
 
-               [MonoTODO ("assemblyName may not have a codebase")]
-               public int ExecuteAssemblyByName (AssemblyName assemblyName, Evidence assemblySecurity, string[] args)
+#if NET_4_0
+               [Obsolete ("Use an overload that does not take an Evidence parameter")]
+#endif
+               public int ExecuteAssemblyByName (AssemblyName assemblyName, Evidence assemblySecurity, params string[] args)
                {
-                       if (assemblyName == null)
-                               throw new ArgumentNullException ("assemblyName");
+                       Assembly a = Assembly.Load (assemblyName, assemblySecurity);
+
+                       return ExecuteAssemblyInternal (a, args);
+               }
+
+#if NET_4_0
+               public int ExecuteAssemblyByName (string assemblyName, params string[] args)
+               {
+                       Assembly a = Assembly.Load (assemblyName, null);
+
+                       return ExecuteAssemblyInternal (a, args);
+               }
 
-                       return ExecuteAssembly (assemblyName.CodeBase, assemblySecurity, args);
+               public int ExecuteAssemblyByName (AssemblyName assemblyName, params string[] args)
+               {
+                       Assembly a = Assembly.Load (assemblyName, null);
+
+                       return ExecuteAssemblyInternal (a, args);
                }
+#endif
 
                public bool IsDefaultAppDomain ()
                {
@@ -1083,9 +1477,17 @@ namespace System {
                {
                        return GetAssemblies (true);
                }
+
+#else // MOONLIGHT
+
+               public int ExecuteAssemblyByName (string assemblyName)
+               {
+                       // critical code in SL that we're not calling in ML
+                       throw new NotImplementedException ();
+               }
 #endif
 
-#if NET_1_1
+#if !NET_2_1
                void _AppDomain.GetIDsOfNames ([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
                {
                        throw new NotImplementedException ();
@@ -1107,5 +1509,42 @@ namespace System {
                        throw new NotImplementedException ();
                }
 #endif
+
+#if NET_4_0 || MOONLIGHT
+               [MonoTODO ("Currently always returns false")]
+               public bool? IsCompatibilitySwitchSet (string value)
+               {
+                       if (value == null)
+                               throw new ArgumentNullException ("value");
+                       // default (at least for SL4) is to return false for unknown values (can't get a null out of it)
+                       return false;
+               }
+
+               [MonoTODO ("Currently always returns false")]
+               public static bool MonitoringIsEnabled { 
+                       get { return false; }
+                       set { throw new NotImplementedException (); }
+               }
+
+               [MonoTODO]
+               public long MonitoringSurvivedMemorySize {
+                       get { throw new NotImplementedException (); }
+               }
+
+               [MonoTODO]
+               public static long MonitoringSurvivedProcessMemorySize {
+                       get { throw new NotImplementedException (); }
+               }
+
+               [MonoTODO]
+               public long MonitoringTotalAllocatedMemorySize {
+                       get { throw new NotImplementedException (); }
+               }
+
+               [MonoTODO]
+               public TimeSpan MonitoringTotalProcessorTime {
+                       get { throw new NotImplementedException (); }
+               }
+#endif
        }
 }