@@ -17,6 +17,9 @@ MidoriGraph; if not, write to the Free Software Foundation, Inc., 
 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
 
+#include <mono/jit/jit.h>
+#include <mono/metadata/object.h>
+#include <mono/metadata/assembly.h>
 
 #include "MonoScriptManager.hpp"
 #include "MonoScript.hpp"
@@ -48,27 +51,52 @@ void MonoScript::initialize(const Node& owner) { 
 
     Property::initialize(owner);
 
+    /*
+    // Load the State class from the assembly.  This is what MonoState needs.
+    MonoClass *klass = mono_class_from_name(
+        mono_assembly_get_image(assembly), "", "State");
+    if (!klass) {
+        throw runtime_error(
+            (string("State class not found in: ") + filename).c_str());
+    }
+
+    // \todo: This part should be in MonoState.
+    MonoObject* obj = mono_object_new(domain, klass);
+    mono_runtime_object_init(obj);
+
+    */
+
+}
+
+
+void MonoScript::connect(const Node& newParent) {
+ 
+    // Get a MonoDomain from the ScriptManager to load the assembly into.
     MonoScriptManager* scriptManager =
         owner.getAncestorProperty<MonoScriptManager>();
+    // \todo Test for no scriptManager found.
 
     domain = scriptManager->getDomain();
     if (!domain){
         throw runtime_error("Domain doesn't exist.");
     }
 
+    // Load the assembly into memory.
     assembly = mono_domain_assembly_open (domain, filename.c_str());
     if (!assembly){
         throw runtime_error((string("File not found: ") + filename).c_str());
     }
 
+    scriptManager->addAssembly(assembly, filename);
 }
 
 
-void MonoScript::execute() {
+void MonoScript::disconnect(const Node& oldParent) {
 
-    char* name[] = {"execute"};
+    MonoScriptManager* scriptManager =
+        owner.getAncestorProperty<MonoScriptManager>();
 
-    mono_jit_exec(domain, assembly, 1, name);
+    scriptManager->removeAssembly(filename);
 }
 
 
 
@@ -37,6 +37,8 @@ class MonoScript: public Property { 
     virtual ~MonoScript();
 
     virtual void initialize(const Node& owner);
+    virtual void connect(const Node& newParent);
+    virtual void disconnect(const Node& oldParent);
 
     static const std::string name() { return "MonoScript"; }    
     virtual const std::string getName() const { return name(); }
@@ -48,8 +50,6 @@ class MonoScript: public Property { 
         return interfaces;
     }  
 
-    void execute();
-
     
   private:
 
 
@@ -48,6 +48,33 @@ void MonoScriptManager::initialize(const Node& owner) { 
 }
 
 
+void MonoScriptManager::addAssembly(AssemblyMap::mapped_type assembly,
+                 AssemblyMap::key_type name) {
+    //\todo read lock for multithreading
+    assemblies.insert(make_pair(name, assembly));
+}
+
+MonoAssembly* MonoScriptManager::getAssembly(AssemblyMap::key_type name) {
+    //\todo read lock for multithreading
+    AssemblyMap::iterator assembly = assemblies.find(name);
+    if (assembly == assemblies.end()) {
+        throw runtime_error((string("Assembly not found: ") + name).c_str());
+    }
+    return assembly->second;
+}
+
+
+void MonoScriptManager::removeAssembly(AssemblyMap::key_type name) {
+    //\todo write lock for multithreading
+    AssemblyMap::iterator assembly = assemblies.find(name);
+    if (assembly == assemblies.end()) {
+        throw runtime_error((string("Assembly not found: ") + name).c_str());
+    }
+    assemblies.erase(assembly);
+}
+
+
+
 MonoScriptManager::RootDomain::RootDomain() {
     mono_assembly_setrootdir(
             "/Library/Frameworks/Mono.framework/Versions/Current/lib");
 
@@ -48,7 +48,20 @@ class MonoScriptManager: public Property { 
         return interfaces;
     }  
 
-    inline MonoDomain* getDomain() { return rootDomain.domain; }
+    MonoDomain* getDomain() {
+        return rootDomain.domain;
+    }
+
+  private:
+    typedef std::map<std::string, MonoAssembly*> AssemblyMap;
+    AssemblyMap assemblies;
+  
+  public:
+
+    void addAssembly(AssemblyMap::mapped_type assembly,
+                     AssemblyMap::key_type name);
+    MonoAssembly* getAssembly(AssemblyMap::key_type name);
+    void removeAssembly(AssemblyMap::key_type name);
 
     
   private:
@@ -60,6 +73,7 @@ class MonoScriptManager: public Property { 
     };
 
     static RootDomain rootDomain;
+
 };
 
 
 
@@ -21,7 +21,7 @@ env.Append(CPPPATH=[ 
     "/Library/Frameworks/Mono.framework/Libraries/glib-2.0/include",
     ])
 
-testAssembly = env.CLIProgram("test.exe", "test.cs",
+testAssembly = env.CLILibrary("test.dll", "test.cs",
                               CSC="gmcs")
 
 monounittest = env.Program("monounittest",
 
@@ -23,6 +23,7 @@ MidoriGraph; if not, write to the Free Software Foundation, Inc., 
 #include "MonoScriptManager.hpp"
 
 using namespace MidoriGraph;
+using namespace std;
 
 
 BOOST_AUTO_TEST_CASE (MonoScriptManager_initialize) {
@@ -31,3 +32,67 @@ BOOST_AUTO_TEST_CASE (MonoScriptManager_initialize) { 
     root.addProperty(new MonoScriptManager());
 }
 
+
+BOOST_AUTO_TEST_CASE (MonoScriptManager_addAssembly) {
+
+    Node root = Node::makeRoot();
+    root.addProperty(new MonoScriptManager());
+
+    root.getProperty<MonoScriptManager>()->
+        addAssembly((MonoAssembly*)(0), "foo");
+}
+
+
+BOOST_AUTO_TEST_CASE (MonoScriptManager_getAssembly) {
+
+    Node root = Node::makeRoot();
+    root.addProperty(new MonoScriptManager());
+
+    root.getProperty<MonoScriptManager>()->
+        addAssembly((MonoAssembly*)(42), "foo");
+
+    MonoAssembly* assembly;
+    BOOST_REQUIRE_NO_THROW(
+        assembly = root.getProperty<MonoScriptManager>()->getAssembly("foo"));
+
+    BOOST_CHECK_EQUAL(int(assembly), 42);
+}
+
+
+BOOST_AUTO_TEST_CASE (MonoScriptManager_getAssembly_fail) {
+
+    Node root = Node::makeRoot();
+    root.addProperty(new MonoScriptManager());
+
+    BOOST_CHECK_THROW(root.getProperty<MonoScriptManager>()->getAssembly("foo"),
+                      runtime_error);
+    
+}
+
+
+BOOST_AUTO_TEST_CASE (MonoScriptManager_removeAssembly) {
+
+    Node root = Node::makeRoot();
+    root.addProperty(new MonoScriptManager());
+
+    root.getProperty<MonoScriptManager>()->
+        addAssembly((MonoAssembly*)(42), "foo");
+
+    MonoAssembly* assembly;
+    BOOST_REQUIRE_NO_THROW(
+        root.getProperty<MonoScriptManager>()->removeAssembly("foo"));
+
+    BOOST_CHECK_THROW(root.getProperty<MonoScriptManager>()->getAssembly("foo"),
+                      runtime_error);
+}
+
+
+BOOST_AUTO_TEST_CASE (MonoScriptManager_removeAssembly_fail) {
+
+    Node root = Node::makeRoot();
+    root.addProperty(new MonoScriptManager());
+
+    BOOST_CHECK_THROW(
+        root.getProperty<MonoScriptManager>()->removeAssembly("foo"),
+        runtime_error);
+}
 
@@ -41,7 +41,7 @@ class MonoScript_testFramework { 
 
         child = root.createChild();
         Property::AttributeMap attributes;
-        attributes.insert(make_pair("filename", string("test.exe")));
+        attributes.insert(make_pair("filename", string("test.dll")));
         child.addProperty(new MonoScript(attributes));
         //        map_list_of<string, any>
         //           ("filename", string("test.dll"))
@@ -59,11 +59,3 @@ BOOST_AUTO_TEST_CASE (MonoScript_initialize) { 
 
 }
 
-
-BOOST_AUTO_TEST_CASE (MonoScript_execute) {
-
-    MonoScript_testFramework test;
-
-    test.child.getProperty<MonoScript>()->execute();
-
-}
 
 using System;
 using System.Runtime.CompilerServices;
 
-class MonoEmbed {
-    [MethodImplAttribute(MethodImplOptions.InternalCall)]
-    extern static string gimme();
+class State {
 
-    static void Main() {
-        Console.WriteLine ("testing!!!!!!!!!!!!!!");
+   State() {
+        Console.WriteLine ("State is constructed!");
     }
 }