edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/Loader.cs;C704650
File: Loader.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/Loader.cs;C704650  (server)    2/26/2009 6:47 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/Loader.cs;assemblydeps
@@ -113,6 +113,12 @@
             _loadPaths = MakeLoadPaths(context.RubyOptions);
             _loadedFiles = new RubyArray();
             _unfinishedFiles = new Stack<string>();
+
+#if !SILVERLIGHT
+            if (!context.RubyOptions.NoAssemblyResolveHook) {
+                new AssemblyResolveHolder(this).HookAssemblyResolve();
+            }
+#endif
         }
 
         private RubyArray/*!*/ MakeLoadPaths(RubyOptions/*!*/ options) {
@@ -250,6 +256,8 @@
             return LoadFromPath(globalScope, self, strPath, flags);
         }
 
+        #region Assemblies
+
         public bool LoadAssembly(string/*!*/ assemblyName, string typeName, bool throwOnError) {
             Utils.Log(String.Format("Loading assembly '{0}' and type '{1}'", assemblyName, typeName), "LOADER");
             
@@ -317,6 +325,60 @@
             return false;
         }
 
+#if !SILVERLIGHT
+        private sealed class AssemblyResolveHolder {
+            private readonly WeakReference _loader;
+
+            public AssemblyResolveHolder(Loader/*!*/ loader) {
+                _loader = new WeakReference(loader);
+            }
+
+            internal void HookAssemblyResolve() {
+                try {
+                    AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolveEvent;
+                } catch (System.Security.SecurityException) {
+                    // We may not have SecurityPermissionFlag.ControlAppDomain. 
+                }
+            }
+
+            private Assembly AssemblyResolveEvent(object sender, ResolveEventArgs args) {
+                Loader loader = (Loader)_loader.Target;
+                if (loader != null) {
+                    return loader.ResolveAssembly(args.Name);
+                } else {
+                    AppDomain.CurrentDomain.AssemblyResolve -= AssemblyResolveEvent;
+                    return null;
+                }
+            }
+        }
+
+        internal Assembly ResolveAssembly(string/*!*/ fullName) {
+            Utils.Log(String.Format("Resolving assembly: '{0}'", fullName), "RESOLVE_ASSEMBLY");
+            
+            AssemblyName assemblyName = new AssemblyName(fullName);
+            ResolvedFile file = FindFile(assemblyName.Name, true, ArrayUtils.EmptyStrings);
+            if (file == null || file.SourceUnit != null) {
+                return null;
+            }
+
+            Utils.Log(String.Format("Assembly '{0}' resolved: found in '{1}'", fullName, file.Path), "RESOLVE_ASSEMBLY");
+            try {
+                Assembly assembly = Platform.LoadAssemblyFromPath(Platform.GetFullPath(file.Path));
+                if (AssemblyName.ReferenceMatchesDefinition(assemblyName, assembly.GetName())) {
+                    Utils.Log(String.Format("Assembly '{0}' loaded for '{1}'", assembly.GetName(), fullName), "RESOLVE_ASSEMBLY");
+                    DomainManager.LoadAssembly(assembly);
+                    return assembly;
+                }
+            } catch (Exception e) {
+                throw new LoadError(e.Message, e);
+            }
+
+            return null;
+        }
+
+#endif
+        #endregion
+
         private class ResolvedFile {
             public readonly SourceUnit SourceUnit;
             public readonly string/*!*/ Path;
@@ -338,7 +400,8 @@
         private bool LoadFromPath(Scope globalScope, object self, string/*!*/ path, LoadFlags flags) {
             Assert.NotNull(path);
 
-            ResolvedFile file = FindFile(path, (flags & LoadFlags.AppendExtensions) != 0);
+            string[] sourceFileExtensions = DomainManager.Configuration.GetFileExtensions();
+            ResolvedFile file = FindFile(path, (flags & LoadFlags.AppendExtensions) != 0, sourceFileExtensions);
             if (file == null) {
                 throw new LoadError(String.Format("no such file to load -- {0}", path));
             }
@@ -422,7 +485,7 @@
             return globalScope != null ? code.Run(globalScope) : code.Run();
         }
 
-        private ResolvedFile FindFile(string/*!*/ path, bool appendExtensions) {
+        private ResolvedFile FindFile(string/*!*/ path, bool appendExtensions, string[] sourceFileExtensions) {
             Assert.NotNull(path);
             bool isAbsolutePath;
             string extension;
@@ -453,12 +516,9 @@
                 throw new LoadError(e.Message, e);
             }
 
-            string[] knownExtensions = DomainManager.Configuration.GetFileExtensions();
-            Array.Sort(knownExtensions, DlrConfiguration.FileExtensionComparer);
-
             // Absolute path -> load paths not consulted.
             if (isAbsolutePath) {
-                return ResolveFile(path, extension, appendExtensions, knownExtensions);
+                return ResolveFile(path, extension, appendExtensions, sourceFileExtensions);
             }
 
             string[] loadPaths = GetLoadPathStrings();
@@ -469,12 +529,12 @@
 
             // If load paths are non-empty and the path starts with .\ or ..\ then MRI also ignores the load paths.
             if (path.StartsWith("./") || path.StartsWith("../") || path.StartsWith(".\\") || path.StartsWith("..\\")) {
-                return ResolveFile(path, extension, appendExtensions, knownExtensions);
+                return ResolveFile(path, extension, appendExtensions, sourceFileExtensions);
             }
 
             foreach (var dir in loadPaths) {
                 try {
-                    ResolvedFile result = ResolveFile(Path.Combine(dir, path), extension, appendExtensions, knownExtensions);
+                    ResolvedFile result = ResolveFile(Path.Combine(dir, path), extension, appendExtensions, sourceFileExtensions);
                     if (result != null) {
                         return result;
                     }
@@ -538,7 +598,7 @@
         private static readonly string[] _LibraryExtensions = new string[] { ".dll", ".so", ".exe" };
 
         private static bool IsKnownExtension(string/*!*/ extension, string[]/*!*/ knownExtensions) {
-            return extension.Length > 0 && Array.BinarySearch(knownExtensions, extension, DlrConfiguration.FileExtensionComparer) >= 0;
+            return extension.Length > 0 && knownExtensions.IndexOf(extension, DlrConfiguration.FileExtensionComparer) >= 0;
         }
 
         private ResolvedFile GetSourceUnit(string/*!*/ path, string/*!*/ extension, bool extensionAppended) {
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyOptions.cs;C737451
File: RubyOptions.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyOptions.cs;C737451  (server)    2/26/2009 6:52 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyOptions.cs;assemblydeps
@@ -32,7 +32,9 @@
         private readonly bool _loadFromDisk;
         private readonly bool _profile;
         private readonly bool _hasSearchPaths;
+        private readonly bool _noAssemblyResolveHook;
         private readonly RubyCompatibility _compatibility;
+
 #if DEBUG
         private static bool _UseThreadAbortForSyncRaise;
         private static bool _CompileRegexps;
@@ -66,6 +68,10 @@
             get { return _profile; }
         }
 
+        public bool NoAssemblyResolveHook {
+            get { return _noAssemblyResolveHook; }
+        }
+
         public ReadOnlyCollection<string>/*!*/ LibraryPaths {
             get { return _libraryPaths; }
         }
@@ -98,6 +104,7 @@
             _savePath = GetOption(options, "SavePath", (string)null);
             _loadFromDisk = GetOption(options, "LoadFromDisk", false);
             _profile = GetOption(options, "Profile", false);
+            _noAssemblyResolveHook = GetOption(options, "NoAssemblyResolveHook", false);
             _libraryPaths = GetStringCollectionOption(options, "LibraryPaths", ';', ',') ?? new ReadOnlyCollection<string>(new[] { "." });
             _hasSearchPaths = GetOption<object>(options, "SearchPaths", null) != null;
             _compatibility = GetCompatibility(options, "Compatibility", RubyCompatibility.Default);
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Tests/Interop/load/custom_assembly_spec.rb;C736874
File: custom_assembly_spec.rb
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Tests/Interop/load/custom_assembly_spec.rb;C736874  (server)    2/27/2009 3:23 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Tests/Interop/load/custom_assembly_spec.rb;assemblydeps
@@ -103,7 +103,17 @@
   end
 end
 
+describe "Static dependency loading" do
+  it "loads a dependent assembly from load paths" do
+    #ruby_exe("dependencies1/test1.rb", :dir => File.dirname(__FILE__)).chomp.should == "1"
+  end
+  
+  it "does propagate load exceptions" do
+    #ruby_exe("dependencies1/test2.rb", :dir => File.dirname(__FILE__)).chomp.should == "true"
+  end
+end
 
+
 describe "Modifying and reloading custom assembly" do 
   before :each do
     @engine = IronRuby.create_engine
===================================================================
add: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Tests/Interop/load/dependencies1
add: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Tests/Interop/load/dependencies1/A
add: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Tests/Interop/load/dependencies1/A.cs
File: A.cs
===================================================================
--- [no source file]
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Tests/Interop/load/dependencies1/A.cs;assemblydeps
@@ -1,0 +1,5 @@
+public class A {
+  public static int Main() {
+    return B.Main();
+  }
+}
\ No newline at end of file
===================================================================
add: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Tests/Interop/load/dependencies1/B
add: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Tests/Interop/load/dependencies1/B.cs
File: B.cs
===================================================================
--- [no source file]
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Tests/Interop/load/dependencies1/B.cs;assemblydeps
@@ -1,0 +1,5 @@
+public class B {
+  public static int Main() {
+    return 1;
+  }
+}
\ No newline at end of file
===================================================================
add: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Tests/Interop/load/dependencies1/build.cmd
File: build.cmd
===================================================================
--- [no source file]
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Tests/Interop/load/dependencies1/build.cmd;assemblydeps
@@ -1,0 +1,3 @@
+tf edit A\A.dll B\B.dll
+csc /target:library /out:B\B.dll B.cs
+csc /target:library /out:A\A.dll /r:B\B.dll A.cs
\ No newline at end of file
===================================================================
add: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Tests/Interop/load/dependencies1/test1.rb
File: test1.rb
===================================================================
--- [no source file]
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Tests/Interop/load/dependencies1/test1.rb;assemblydeps
@@ -1,0 +1,9 @@
+# A.dll statically references B.dll in A.Main method.
+# We should auto-load B.dll from B directory.
+
+$:.clear
+$: << "A"
+$: << "B"
+
+require 'a'
+p A.Main
\ No newline at end of file
===================================================================
add: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Tests/Interop/load/dependencies1/test2.rb
File: test2.rb
===================================================================
--- [no source file]
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Tests/Interop/load/dependencies1/test2.rb;assemblydeps
@@ -1,0 +1,22 @@
+# A.dll statically references B.dll in A.Main method.
+# We should auto-load B.dll from B directory.
+
+class C
+  def to_str
+    raise Exception.new("!!!") if $raise
+    "B"
+  end
+end
+
+$:.clear
+$: << "A"
+$: << C.new
+
+require 'a'
+$raise = true
+
+begin
+  p A.Main
+rescue
+  p $!.class.name == "System::IO::FileLoadException"
+end
\ No newline at end of file
===================================================================
add: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Tests/Interop/load/dependencies1/A/A.dll
A.dll: files differ
add: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Tests/Interop/load/dependencies1/A/b.rb
File: b.rb
===================================================================
--- [no source file]
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Tests/Interop/load/dependencies1/A/b.rb;assemblydeps
@@ -1,0 +1,1 @@
+raise Exception("This should not be loaded")
\ No newline at end of file
===================================================================
add: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Tests/Interop/load/dependencies1/B/B.dll
B.dll: files differ
