return rc;
 }
 
+/**
+ * @brief Find a method in the instance.
+ *
+ * @param name  the method's name
+ * @return      NULL: method not found
+ *              otherwise: the method description
+ */
+RplASMethod* RplSymbolSpace::findMethod(const QString& name) const
+{
+    RplASMethod* rc = NULL;
+    if (m_methods.contains(name))
+        rc = m_methods[name];
+    return rc;
+}
+
 /**
  * @brief Writes the content of the instance into a file.
  *
 
     m_threads.reserve(8);
 }
 
+/**
+ * @brief Executes the program in a module.
+ *
+ * @param module    the module's name
+ */
+void RplVirtualMachine::executeModule(const QString& module)
+{
+    RplSymbolSpace* space = m_tree.findmodule(module);
+    if (space == NULL)
+        throw RplVmException("module not found: %s", module.toUtf8().constData());
+    RplStackFrame frame(space);
+    RplSymbolSpace* mainSpace = NULL;
+    RplASItem* mainStatements = NULL;
+    RplASMethod* method = space->findMethod("main");
+    if (method != NULL){
+        mainStatements = method->child();
+        mainSpace = method->symbols();
+    }
+    addThread(space->body(), space, mainStatements, mainSpace);
+}
+
 /**
  * @brief Adds a thread to the instance.
  *
- * @param program   the statement list to execute
- * @param space     the current symbol space
+ * @param initialization        the statements for initialization
+ * @param spaceInitialization   the symbol space of the initialization
+ * @param statements            the statement list to execute. This is normally
+ *                              the body of the main program
+ * @param space                 the symbol space of the statements, normally
+ *                              the symbol space of the main program
  * @param maxStack  the maximal number of nested stack frames.
  *                  <= 0: use the default
  */
-void RplVirtualMachine::addThread(RplASItem* program, RplSymbolSpace* space,
+void RplVirtualMachine::addThread(RplASItem* initialization,
+                                  RplSymbolSpace* spaceInitialization,
+                                  RplASItem* statements,
+                                  RplSymbolSpace* space,
                                   int maxStack)
 {
     RplVMThread* thread = new RplVMThread(
                 maxThread <= 0 ? m_maxStack : maxStack, self);
     m_threads.append(thread);
-    thread->execute(program, space);
+    if (initialization != NULL){
+        thread->execute(initialization, spaceInitialization);
+    }
+    if (statements != NULL)
+        thread->execute(statements, space);
 }
 /**
  * @brief Tests whether a given flag is set.
 
 public:
     RplVirtualMachine(RplASTree& tree, RplSource& source, int maxStack = 1024);
 public:
-    void addThread(RplASItem* program, RplSymbolSpace* space, int maxStack = 0);
+    void executeModule(const QString& module);
+    void addThread(RplASItem* initialization,
+                   RplSymbolSpace* spaceInitialization,
+                   RplASItem* statements, RplSymbolSpace* space,
+                   int maxStack = 0);
     bool hasFlag(VMFlag flag) const;
     void setFlag(VMFlag flag);
     void clearFlag(VMFlag flag);
 
         fnExpected += (char) QDir::separator().toLatin1();
         fnExpected += fileExpected;
         QByteArray fnCurrent = getTempFile(fileExpected, "rplvm");
+        vm.executeModule("<test>");
         vm.dump(fnCurrent, RplASTree::DMP_NO_GLOBALS);
         assertEqualFiles(fnExpected.constData(), fnCurrent.constData(),
                          __FILE__, lineNo);