diff --git a/core/trunk/core/tests/class/DataAccessService_Database.php b/core/trunk/core/tests/class/DataAccessService_Database.php
index aa948db47a4b6f5e8644703b06ce80d32558c38c..71afebd8eeec520e26b38a87fb20930f38b03d77 100644
--- a/core/trunk/core/tests/class/DataAccessService_Database.php
+++ b/core/trunk/core/tests/class/DataAccessService_Database.php
@@ -27,7 +27,8 @@ class DataAccessService_Database
     {
         $this->databaseObject->connect();
         if(!$this->inTransaction) {
-            $this->databaseObject->query('START TRANSACTION');
+            //echo "<br/>DB Start transaction";
+            $this->databaseObject->start_transaction();
             $this->inTransaction = true;
         }
     }
@@ -35,7 +36,8 @@ class DataAccessService_Database
     public function commit()
     {
         if($this->inTransaction) {
-            $this->databaseObject->query('COMMIT');
+            //echo "<br/>DB Commit";
+            $this->databaseObject->commit();
             $this->inTransaction = false;
         }
     }
@@ -43,7 +45,8 @@ class DataAccessService_Database
     public function rollback()
     {
         if($this->inTransaction) {
-            $this->databaseObject->query('ROLLBACK');
+            //echo "<br/>DB Rollback";
+            $this->databaseObject->rollback();
             $this->inTransaction = false;
         }
     }
@@ -151,6 +154,7 @@ class DataAccessService_Database
                     $selectFilterExpression
                 );
             }
+            //echo "<br/>filter expression $filterExpression";
             $filterExpression = str_replace('$filter', $filter, $filterExpression);
             $whereParts[] = $filterExpression;
         }
@@ -161,29 +165,32 @@ class DataAccessService_Database
             && get_class($parentObject) != 'DataObjectDocument'
             && $relation = $this->getRelation($objectElement, $parentObject)
         ) {
-            if(!$relationExpression = 
+            //echo "<br/>Found relation between " . $objectElement->getName() . " and " . $parentObject->nodeName;
+            /*if(!$relationExpression = 
                 $this->getXRefs($objectElement, 'relationExpression')
-            ) {
+            ) {*/
                 $relationExpression = 
                     $this->createRelationExpression(
                         $objectElement, 
                         $relation
                     );
-                $this->addXRefs(
+            /*    $this->addXRefs(
                     $objectElement, 
                     'relationExpression', 
                     $relationExpression
                 );
-            }
+            }*/
+            
             if($relationExpression) {
-                preg_match('/\$\w+/', $relationExpression, $params);
-                foreach($params as $paramName) {
+                preg_match_all('/\$\w+/', $relationExpression, $params);
+                foreach($params[0] as $paramName) {
                     $attrName = substr($paramName, 1);
                     //echo "<br/>Relation between " . $parentObject->getName() . " and " . $objectElement->getName() . " ==> key is $paramName value of $attrName is " . get_class($parentObject) . " ". $parentObject->$attrName;
                     $value = $parentObject->$attrName;
                     if(!$value || $value == '') $value = "99999999";
                     $relationExpression = str_replace($paramName, $value, $relationExpression);
                 }
+                //echo "<br/>Relation expression is '$relationExpression'"; 
                 $whereParts[] = $relationExpression;
             }
         }
@@ -229,7 +236,7 @@ class DataAccessService_Database
         $selectQuery = implode(' ', $selectParts);
         
         $this->queries[] = $selectQuery;
-        //echo "<pre>SELECT QUERY = " . $selectQuery . "</pre>";
+        //  echo "<pre>SELECT QUERY = " . $selectQuery . "</pre>";
         
         try {
             $this->databaseObject->connect();
@@ -260,7 +267,9 @@ class DataAccessService_Database
                         $dataObjectDocument
                     );
                     foreach($recordSet as $columnName => $columnValue) {
-                        $dataObject->$columnName = $columnValue;
+                        if($columnValue != '') {
+                            $dataObject->$columnName = $columnValue;
+                        }
                     } 
                 //}
                 $parentObject[] = $dataObject;
diff --git a/core/trunk/core/tests/class/DataObject.php b/core/trunk/core/tests/class/DataObject.php
index 9fd37e6f5d0f6c1b9e1033aae58429384c629449..39e2623bec5afaff28cdd2a58b3da5af985f2054 100644
--- a/core/trunk/core/tests/class/DataObject.php
+++ b/core/trunk/core/tests/class/DataObject.php
@@ -432,13 +432,11 @@ class DataObjectElement
     
     // ARRAYACCESS METHODS
     //*************************************************************************
-    public function offsetSet($offset, $value) 
+    public function offsetSet($offset, $dataObject) 
     {
-        if($value->ownerDocument != $this->onwerDocument) {
-            $dataObject = $this->ownerDocument->importNode($value, true);
-        } else {
-            $dataObject = $value;
-        }
+        if($dataObject->ownerDocument != $this->onwerDocument) {
+            $dataObject = $this->ownerDocument->importNode($dataObject, true);
+        } 
         $objectName = $dataObject->getName();
         $refDataObject = $this->getCommentDataObject($objectName);
         if(is_null($offset)) $offset = 999999;
@@ -454,7 +452,6 @@ class DataObjectElement
             $dataObject, 
             $refDataObject->nextSibling
             );
-        return;
     }
     
     public function offsetExists($offset) 
@@ -675,7 +672,7 @@ class DataObjectElement
         return $this->C14N(false,true);
     }
     
-    public function show($withComments=true, $prettyAttrs=false)
+    public function show($withComments=true, $prettyAttrs=false, $returnValue=false)
     {
         // add marker linefeeds to aid the pretty-tokeniser (adds a linefeed between all tag-end boundaries)
         $xml = preg_replace('/(>)(<)(\/*)/', "$1\n$2$3", $this->C14N(false, $withComments));
@@ -716,10 +713,13 @@ class DataObjectElement
             $token   = strtok("\n"); // get the next token
             $pad    += $indent; // update the pad size for subsequent lines    
         } 
-        
-        echo "<pre>";
-        echo htmlspecialchars($result);
-        echo "</pre>";
+        if($returnValue) {
+            return $result;
+        } else {
+            echo "<pre>";
+            echo htmlspecialchars($result);
+            echo "</pre>";
+        }
     }
     
     private function showAttr($token, $pad)
@@ -844,19 +844,44 @@ class DataObjectLog
 **                                                                          **
 *****************************************************************************/
 class DataObjectList
-    implements IteratorAggregate, ArrayAccess
+    implements IteratorAggregate, ArrayAccess, Countable
 {
     
     private $storage = array();
+    public $length;
     
-    public function DataObjectList($nodeList)
+    public function DataObjectList($nodeList=false)
     {
-        $l = $nodeList->length;
-        for($i=0; $i<$l; $i++) {
-            $this->storage[$i] = $nodeList->item($i);
-        }   
+        if($nodeList) {
+            $l = $nodeList->length;
+            for($i=0; $i<$l; $i++) {
+                $this->storage[$i] = $nodeList->item($i);
+            } 
+        }
+        $this->length = count($this->storage);
     }
-
+    
+    public function show() 
+    {
+        $showArray = array();
+        for($i=0; $i<count($this->storage); $i++) {
+            $showArray[] = htmlspecialchars($this->storage[$i]->show(true, false, true));
+        }
+        echo "<pre>";
+        print_r($showArray);
+        echo "</pre>";
+        
+    }
+    
+    //*************************************************************************
+    // MAGIC METHODS
+    //*************************************************************************
+    public function __get($name)
+    {
+        if($name == 'length') return count($this->storage);
+    }
+    
+    
     //*************************************************************************
     // DOM NODELITS EMULATION
     //*************************************************************************    
@@ -886,12 +911,21 @@ class DataObjectList
         return new ArrayIterator($this->storage);
     }
 
+    //*************************************************************************
+    // COUNTABLE METHODS
+    //*************************************************************************
+    public function count()
+    {
+        return count($this->storage);
+    } 
+    
     //*************************************************************************
     // ARRAYACCESS METHODS
     //*************************************************************************
     public function offsetSet($offset, $value) 
     {
         $this->storage[$offset] = $value;
+        $this->length = count($this->storage);
     }
     
     public function offsetExists($offset) 
@@ -902,6 +936,7 @@ class DataObjectList
     public function offsetUnset($offset) 
     {
         unset($this->storage[$offset]);
+        $this->length = count($this->storage);
     }
     
     public function offsetGet($offset) 
diff --git a/core/trunk/core/tests/class/DataObjectController.php b/core/trunk/core/tests/class/DataObjectController.php
index 9830e6edd700c202f97cd15fda60bd16bb94d2d9..bcadfc11056b044510e589deac1766ec93841fde 100644
--- a/core/trunk/core/tests/class/DataObjectController.php
+++ b/core/trunk/core/tests/class/DataObjectController.php
@@ -23,8 +23,9 @@ class DataObjectController
     public $dataAccessServices = array();
     protected $XRefs = array();
     protected $messageController;
-   
-     
+    public $inTransaction;
+    public $transactionControl;
+       
     //*************************************************************************
     // CONSTRUCTOR
     //*************************************************************************
@@ -223,10 +224,9 @@ class DataObjectController
         
         if(!$objectElement->isReadable()) throw new maarch\Exception("Object $objectName can not be read");
         
-        $dataObject = $dataObjectDocument;
         $this->readDataObject(
             $objectElement, 
-            $dataObject, 
+            $dataObjectDocument, 
             $dataObjectDocument,
             $key,
             $readChildren
@@ -234,20 +234,34 @@ class DataObjectController
         return $dataObjectDocument->documentElement;
     }
     
-    public function save($dataObject, $saveChildren=true)
-    {
+    public function save(
+        $dataObject, 
+        $saveChildren = true
+    ) {
         $objectElement = $this->getElementByName($dataObject->tagName);
         $dataObjectDocument = $dataObject->ownerDocument;
-        $key = $this->saveDataObject(
-            $objectElement, 
-            $dataObject,
-            $saveChildren
-        );   
-        
-        return $key;
+        if(!$this->inTransaction) {
+            $this->startTransaction('controller');
+        }
+        try {
+            $key = $this->saveDataObject(
+                $objectElement, 
+                $dataObject,
+                $saveChildren
+            );
+            if($this->transactionControl == 'controller') {
+                $this->commit();
+            }
+            return $key;
+        } catch (maarch\Exception $e) {
+            $this->rollback();
+            throw $e;
+        }
     }
     
-    public function readChildren($dataObject) {
+    public function readChildren(
+        $dataObject
+    ) {
         $objectName = $dataObject->getName();
         $objectElement = $this->getElementByName($objectName);
         $this->readChildDataObjects(
@@ -283,6 +297,26 @@ class DataObjectController
         $this->deleteDataObject($objectElement, $dataObject);
     }
     
+    public function copy(
+        $dataObject, 
+        $newName=false
+    ){
+        if(!$newName) $newName = $dataObject->nodeName;
+        $newObject = $dataObject->ownerDocument->createElement($newName);
+        if ($dataObject->attributes->length) {
+            foreach ($dataObject->attributes as $attribute) {
+                $newObject->setAttribute($attribute->nodeName, $attribute->nodeValue);
+            }
+        }
+        while ($dataObject->firstChild) {
+            $newObject->appendChild($dataObject->firstChild);
+        }
+        $newObject->clearLogs();
+        $newObject->logCreate();
+        //$dataObject->parentNode->replaceChild($newObject, $dataObject);
+        return $newObject;
+    }
+    
     public function validate($dataObject) 
     {
         $messageController = new MessageController();
@@ -452,7 +486,6 @@ class DataObjectController
         $key=false,
         $readChildren=true
     ) {      
-     
         try {
             if($dataAccessService = 
                 $this->getDataAccessService($objectElement)
@@ -478,16 +511,16 @@ class DataObjectController
             
             if($readChildren) {
                 // Process newly created child objects
-                $childObjects = 
+                $newObjects = 
                     $parentObject->getChildNodesByTagName(
                         $objectElement->getName()
                     );
-                $m = $childObjects->length;
+                $m = $newObjects->length;
                 for($j=0; $j<$m; $j++) {
-                    $childObject = $childObjects->item($j);
+                    $newObject = $newObjects->item($j);
                     $this->readChildDataObjects(
                         $objectElement,
-                        $childObject, 
+                        $newObject, 
                         $dataObjectDocument
                     );
                 }
@@ -511,14 +544,13 @@ class DataObjectController
             if(!$objectNode->isReadable()) continue;
             $refNode = $this->getRefNode($objectNode);
             if(!$refNode->hasDatasource()) continue;
-            //for($j=0; $j<$m; $j++) {
-            //    $childObject = $childObjects->item($j);
-                $this->readDataObject(
-                    $refNode, 
-                    $dataObject, 
-                    $dataObjectDocument
-                );
-            //}
+            //echo "<br/>Read child of " . $objectElement->getName() . " named " . $refNode->getName();
+            $this->readDataObject(
+                $refNode, 
+                $dataObject, 
+                $dataObjectDocument
+            );
+            
         }
     }
     
@@ -529,12 +561,10 @@ class DataObjectController
     ) {
         try { 
             $refElement = $this->getRefNode($objectElement);
-            
+            //echo "<br>Save " . $refElement->getName();
             if($dataAccessService = 
                 $this->getDataAccessService($refElement)
             ) {
-                $dataAccessService->startTransaction();
-                
                 if($dataObject->isCreated() 
                     && !$dataObject->isDeleted()
                 ) {
@@ -550,8 +580,7 @@ class DataObjectController
                     if($saveChildren) {
                         $this->saveChildDataObjects(
                             $objectElement,
-                            $dataObject,
-                            $key
+                            $dataObject
                         );
                     }
                 } elseif ($dataObject->isRead()
@@ -569,8 +598,7 @@ class DataObjectController
                     if($saveChildren) {
                         $this->saveChildDataObjects(
                             $objectElement,
-                            $dataObject,
-                            $key
+                            $dataObject
                         );
                     }
                 } elseif ($dataObject->isDeleted()) {
@@ -586,10 +614,8 @@ class DataObjectController
                         );
                 } 
             } 
-            $dataAccessService->commit();
             return $key;
         } catch (maarch\Exception $e) {   
-            $dataAccessService->rollback();
             throw $e;
         }
     }
@@ -615,8 +641,7 @@ class DataObjectController
     
     protected function saveChildDataObjects(
         $objectElement, 
-        $dataObject, 
-        $returnKey = false
+        $dataObject
     ) {
         $objectContents = $this->getObjectContents($objectElement);
         $l = count($objectContents);
@@ -627,8 +652,15 @@ class DataObjectController
             if(!$refNode->hasDatasource()) continue;
             
             // Get relation between dataObject and child
-            //echo "<br/>Relation between " . $refNode->getName() . " and " . $dataObject->getName();
+            //echo "<br/>Relation between child " . $refNode->getName() . " and parent " . $dataObject->getName();
             $relation = $this->getRelation($refNode, $dataObject);
+            if(!$relation) {
+                throw new maarch\Exception(
+                    "No relation defined in schema between " . $refNode->getName() 
+                    . " and " . $dataObject->nodeName 
+                    . "! Rolling back transaction"
+                );
+            }
             $fkeys = $this->query('./das:foreign-key', $relation);
             $n = $fkeys->length;
             
@@ -642,13 +674,13 @@ class DataObjectController
                 $childObject = $childObjects->item($j);
                 
                 // Assign key values to child if needed
-                if($returnKey) {
-                    for($k=0; $k<$n; $k++) {
-                        $fkey = $fkeys->item($k);
-                        $parentKey = $fkey->getAttribute('parent-key');
-                        $childKey = $fkey->getAttribute('child-key');
-                        $childObject->$childKey = $returnKey->$parentKey;
-                    }
+                for($k=0; $k<$n; $k++) {
+                    $fkey = $fkeys->item($k);
+                    $parentKey = $fkey->getAttribute('parent-key');
+                    $childKey = $fkey->getAttribute('child-key');
+                    //echo "<br/>parentkey is $parentKey, childkey is $childKey";
+                    $childObject->$childKey = $dataObject->$parentKey;
+                    //echo " --> childkey set to :" . $childObject->$childKey;
                 }
                 
                 $this->saveDataObject(
@@ -751,20 +783,22 @@ class DataObjectController
         } 
     }
     
-    public function startTransaction()
+    public function startTransaction($transactionControl='caller')
     {
-        for($i=0; $i<count($this->dataAccessServices); $i++) {
-            $dataAccessService = $dataAccessServices[$i];
+        //echo "<br/>Starting transaction for control " . $transactionControl;
+        $this->transactionControl = $transactionControl;
+        foreach($this->dataAccessServices as $dataAccessService) {
             if(method_exists($dataAccessService, 'startTransaction')) {
                 $dataAccessService->startTransaction();
             }
         }
+        $this->inTransaction = true;
     }
     
     public function commit()
     {
-        for($i=0; $i<count($this->dataAccessServices); $i++) {
-            $dataAccessService = $dataAccessServices[$i];
+        //echo "<br/>Commit transaction for control " . $this->transactionControl;
+        foreach($this->dataAccessServices as $dataAccessService) {
             if(method_exists($dataAccessService, 'commit')) {
                 $dataAccessService->commit();
             }
@@ -773,8 +807,8 @@ class DataObjectController
     
     public function rollback()
     {
-        for($i=0; $i<count($this->dataAccessServices); $i++) {
-            $dataAccessService = $dataAccessServices[$i];
+        //echo "<br/>Rollbak transaction for control " . $this->transactionControl;
+        foreach($this->dataAccessServices as $dataAccessService) {
             if(method_exists($dataAccessService, 'rollback')) {
                 $dataAccessService->rollback();
             }
diff --git a/core/trunk/core/tests/class/Schema.php b/core/trunk/core/tests/class/Schema.php
index 92f7cf7821484a64fcd82a9333e1d8b5cde83ec5..6129833082f161dddfbd60aca9c438af11f535bb 100644
--- a/core/trunk/core/tests/class/Schema.php
+++ b/core/trunk/core/tests/class/Schema.php
@@ -43,7 +43,12 @@ class Schema
     public function includeXSD($schema, $includeSchemaLocation, $rootSchema)
     {
         $includeSchema = new Schema();
-        $includeSchema->loadXSD($includeSchemaLocation, $rootSchema);
+        if(file_exists('custom' . DIRECTORY_SEPARATOR . $includeSchemaLocation)) {
+            $includeSchemaPath = 'custom' . DIRECTORY_SEPARATOR . $includeSchemaLocation;
+        } else {
+            $includeSchemaPath = $includeSchemaLocation;
+        }
+        $includeSchema->loadXSD($includeSchemaPath, $rootSchema);
         $schemaContents = $includeSchema->documentElement->childNodes;
         for($j=0; $j<$schemaContents->length; $j++) {
             $importNode = $schemaContents->item($j);