MDL-22164 backup - clean already implemented old code (wip)
authorEloy Lafuente <stronk7@moodle.org>
Mon, 30 Aug 2010 00:27:38 +0000 (00:27 +0000)
committerEloy Lafuente <stronk7@moodle.org>
Mon, 30 Aug 2010 00:27:38 +0000 (00:27 +0000)
backup/restorelib.php

index ed126a2..9ee0a66 100644 (file)
@@ -23,38 +23,6 @@ define('RESTORE_GROUPINGS_ONLY', 2);
  */
 define('RESTORE_GROUPS_GROUPINGS', 3);
 
-    //This function unzips a zip file in the same directory that it is
-    //It automatically uses pclzip or command line unzip
-    function restore_unzip ($file) {
-
-        return unzip_file($file, '', false);
-
-    }
-
-    //This function checks if moodle.xml seems to be a valid xml file
-    //(exists, has an xml header and a course main tag
-    function restore_check_moodle_file ($file) {
-
-        $status = true;
-
-        //Check if it exists
-        if ($status = is_file($file)) {
-            //Open it and read the first 200 bytes (chars)
-            $handle = fopen ($file, "r");
-            $first_chars = fread($handle,200);
-            $status = fclose ($handle);
-            //Chek if it has the requires strings
-            if ($status) {
-                $status = strpos($first_chars,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
-                if ($status !== false) {
-                    $status = strpos($first_chars,"<MOODLE_BACKUP>");
-                }
-            }
-        }
-
-        return $status;
-    }
-
     //This function iterates over all modules in backup file, searching for a
     //MODNAME_refresh_events() to execute. Perhaps it should ve moved to central Moodle...
     function restore_refresh_events($restore) {
@@ -80,6335 +48,1745 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
         return $status;
     }
 
-    //This function makes all the necessary calls to xxxx_decode_content_links_caller()
-    //function in each module/block/course format..., passing them the desired contents to be decoded
-    //from backup format to destination site/course in order to mantain inter-activities
-    //working in the backup/restore process
-    function restore_decode_content_links($restore) {
+    //Called to set up any course-format specific data that may be in the file
+    function restore_set_format_data($restore,$xml_file) {
         global $CFG, $DB;
 
         $status = true;
-
-        if (!defined('RESTORE_SILENTLY')) {
-            echo "<ul>";
-        }
-
-        // Recode links in the course summary.
-        if (!defined('RESTORE_SILENTLY')) {
-            echo '<li>' . get_string('from') . ' ' . get_string('course');
-        }
-        $course = $DB->get_record('course', array('id'=>$restore->course_id), 'id,summary');
-        $coursesummary = backup_todb($course->summary); // Exception: Process FILEPHP (not available when restored) MDL-18222
-        $coursesummary = restore_decode_content_links_worker($coursesummary, $restore);
-        if ($coursesummary != $course->summary) {
-            $course->summary = $coursesummary;
-            $DB->update_record('course', $course);
+        //Check it exists
+        if (!file_exists($xml_file)) {
+            return false;
         }
-        if (!defined('RESTORE_SILENTLY')) {
-            echo '</li>';
+        //Load data from XML to info
+        if(!($info = restore_read_xml_formatdata($xml_file))) {
+                return false;
         }
 
-        // Recode links in section summaries.
-        $sections = $DB->get_records('course_sections', array('course'=>$restore->course_id), 'id', 'id,summary');
-        if ($sections) {
-            if (!defined('RESTORE_SILENTLY')) {
-                echo '<li>' . get_string('from') . ' ' . get_string('sections');
-            }
-            foreach ($sections as $section) {
-                $sectionsummary = restore_decode_content_links_worker($section->summary, $restore);
-                if ($sectionsummary != $section->summary) {
-                    $section->summary = $sectionsummary;
-                    $DB->update_record('course_sections', $section);
+        //Process format data if there is any
+        if (isset($info->format_data)) {
+                if(!$format=$DB->get_field('course','format', array('id'=>$restore->course_id))) {
+                    return false;
                 }
-            }
-            if (!defined('RESTORE_SILENTLY')) {
-                echo '</li>';
-            }
-        }
-
-        // Restore links in modules.
-        foreach ($restore->mods as $name => $info) {
-            //If the module is being restored
-            if (isset($info->restore) && $info->restore == 1) {
-                //Check if the xxxx_decode_content_links_caller exists
-                include_once("$CFG->dirroot/mod/$name/restorelib.php");
-                $function_name = $name."_decode_content_links_caller";
-                if (function_exists($function_name)) {
-                    if (!defined('RESTORE_SILENTLY')) {
-                        echo "<li>".get_string ("from")." ".get_string("modulenameplural",$name);
-                    }
-                    $status = $function_name($restore) && $status;
-                    if (!defined('RESTORE_SILENTLY')) {
-                        echo '</li>';
-                    }
+                // If there was any data then it must have a restore method
+                $file=$CFG->dirroot."/course/format/$format/restorelib.php";
+                if(!file_exists($file)) {
+                    return false;
                 }
-            }
+                require_once($file);
+                $function=$format.'_restore_format_data';
+                if(!function_exists($function)) {
+                    return false;
+                }
+                return $function($restore,$info->format_data);
         }
 
-        // For the course format call its decode_content_links method (if it exists)
-        $format = $DB->get_field('course','format', array('id'=>$restore->course_id));
-        if (file_exists("$CFG->dirroot/course/format/$format/restorelib.php")) {
-            include_once("$CFG->dirroot/course/format/$format/restorelib.php");
-            $function_name = $format.'_decode_format_content_links_caller';
+        // If we got here then there's no data, but that's cool
+        return true;
+    }
 
-            if (function_exists($function_name)) {
-                if (!defined('RESTORE_SILENTLY')) {
-                    echo "<li>".get_string ("from")." ".get_string("format").' '.$format;
-                }
-                $status = $function_name($restore);
-                if (!defined('RESTORE_SILENTLY')) {
-                    echo '</li>';
-                }
-            }
-        }
 
-        // Process all html text also in blocks too
-        if (!defined('RESTORE_SILENTLY')) {
-            echo '<li>'.get_string ('from').' '.get_string('blocks');
-        }
+    /**
+     * This function creates all the gradebook data from xml
+     */
+    function restore_create_gradebook($restore,$xml_file) {
+        global $CFG, $DB;
 
-        if ($blocks = $DB->get_records('block', array('visible'=>1))) {
-            foreach ($blocks as $block) {
-                if ($blockobject = block_instance($block->name)) {
-                    $blockobject->decode_content_links_caller($restore);
-                }
-            }
+        $status = true;
+        //Check it exists
+        if (!file_exists($xml_file)) {
+            return false;
         }
 
-        if (!defined('RESTORE_SILENTLY')) {
-            echo '</li>';
-        }
+        // Get info from xml
+        // info will contain the number of record to process
+        $info = restore_read_xml_gradebook($restore, $xml_file);
 
-        // Restore links in questions.
-        require_once("$CFG->dirroot/question/restorelib.php");
-        if (!defined('RESTORE_SILENTLY')) {
-            echo '<li>' . get_string('from') . ' ' . get_string('questions', 'quiz');
-        }
-        $status = question_decode_content_links_caller($restore) && $status;
-        if (!defined('RESTORE_SILENTLY')) {
-            echo '</li>';
+        // If we have info, then process
+        if (empty($info)) {
+            return $status;
         }
 
-        if (!defined('RESTORE_SILENTLY')) {
-            echo "</ul>";
+        if (empty($CFG->disablegradehistory) and isset($info->gradebook_histories) and $info->gradebook_histories == "true") {
+            $restore_histories = true;
+        } else {
+            $restore_histories = false;
         }
 
-        return $status;
-    }
+        // make sure top course category exists
+        $course_category = grade_category::fetch_course_category($restore->course_id);
+        $course_category->load_grade_item();
 
-    //This function is called from all xxxx_decode_content_links_caller(),
-    //its task is to ask all modules (maybe other linkable objects) to restore
-    //links to them.
-    function restore_decode_content_links_worker($content,$restore) {
-        global $CFG, $DB;
+        // we need to know if all grade items that were backed up are being restored
+        // if that is not the case, we do not restore grade categories nor gradeitems of category type or course type
+        // i.e. the aggregated grades of that category
+
+        $restoreall = true;  // set to false if any grade_item is not selected/restored or already exist
+        $importing  = !empty($SESSION->restore->importing);
+
+        if ($importing) {
+            $restoreall = false;
+
+        } else {
+            $prev_grade_items = grade_item::fetch_all(array('courseid'=>$restore->course_id));
+            $prev_grade_cats  = grade_category::fetch_all(array('courseid'=>$restore->course_id));
 
-        foreach($restore->mods as $name => $info) {
-            $function_name = $name."_decode_content_links";
-            if (function_exists($function_name)) {
-                $content = $function_name($content,$restore);
+             // if any categories already present, skip restore of categories from backup - course item or category already exist
+            if (count($prev_grade_items) > 1 or count($prev_grade_cats) > 1) {
+                $restoreall = false;
             }
-        }
+            unset($prev_grade_items);
+            unset($prev_grade_cats);
+
+            if ($restoreall) {
+                if ($recs = $DB->get_records("backup_ids", array('table_name'=>'grade_items', 'backup_code'=>$restore->backup_unique_code), "", "old_id")) {
+                    foreach ($recs as $rec) {
+                        if ($data = backup_getid($restore->backup_unique_code,'grade_items',$rec->old_id)) {
+
+                            $info = $data->info;
+                            // do not restore if this grade_item is a mod, and
+                            $itemtype = backup_todb($info['GRADE_ITEM']['#']['ITEMTYPE']['0']['#']);
+
+                            if ($itemtype == 'mod') {
+                                $olditeminstance = backup_todb($info['GRADE_ITEM']['#']['ITEMINSTANCE']['0']['#']);
+                                $itemmodule      = backup_todb($info['GRADE_ITEM']['#']['ITEMMODULE']['0']['#']);
 
-        // For the current format, call decode_format_content_links if it exists
-        static $format_function_name;
-        if (!isset($format_function_name)) {
-            $format_function_name = false;
-            if ($format = $DB->get_field('course','format', array('id'=>$restore->course_id))) {
-                if (file_exists("$CFG->dirroot/course/format/$format/restorelib.php")) {
-                    include_once("$CFG->dirroot/course/format/$format/restorelib.php");
-                    $function_name = $format.'_decode_format_content_links';
-                    if (function_exists($function_name)) {
-                        $format_function_name = $function_name;
+                                if (empty($restore->mods[$itemmodule]->granular)) {
+                                    continue;
+                                } else if (!empty($restore->mods[$itemmodule]->instances[$olditeminstance]->restore)) {
+                                    continue;
+                                }
+                                // at least one activity should not be restored - do not restore categories and manual items at all
+                                $restoreall = false;
+                                break;
+                            }
+                        }
                     }
                 }
             }
         }
-        // If the above worked - then we have a function to call
-        if ($format_function_name) {
-            $content = $format_function_name($content, $restore);
+
+        // Start ul
+        if (!defined('RESTORE_SILENTLY')) {
+            echo '<ul>';
         }
 
-        // For each block, call its encode_content_links method
-        static $blockobjects = null;
-        if (!isset($blockobjects)) {
-            $blockobjects = array();
-            if ($blocks = $DB->get_records('block', array('visible'=>1))) {
-                foreach ($blocks as $block) {
-                    if ($blockobject = block_instance($block->name)) {
-                        $blockobjects[] = $blockobject;
+        // array of restored categories - speedup ;-)
+        $cached_categories = array();
+        $outcomes          = array();
+
+    /// Process letters
+        $context = get_context_instance(CONTEXT_COURSE, $restore->course_id);
+        // respect current grade letters if defined
+        if ($status and $restoreall and !$DB->record_exists('grade_letters', array('contextid'=>$context->id))) {
+            if (!defined('RESTORE_SILENTLY')) {
+                echo '<li>'.get_string('gradeletters','grades').'</li>';
+            }
+            // Fetch recordset_size records in each iteration
+            $recs = $DB->get_records("backup_ids", array('table_name'=>'grade_letters', 'backup_code'=>$restore->backup_unique_code),
+                                        "",
+                                        "old_id");
+            if ($recs) {
+                foreach ($recs as $rec) {
+                    // Get the full record from backup_ids
+                    $data = backup_getid($restore->backup_unique_code,'grade_letters',$rec->old_id);
+                    if ($data) {
+                        $info = $data->info;
+                        $dbrec = new object();
+                        $dbrec->contextid     = $context->id;
+                        $dbrec->lowerboundary = backup_todb($info['GRADE_LETTER']['#']['LOWERBOUNDARY']['0']['#']);
+                        $dbrec->letter        = backup_todb($info['GRADE_LETTER']['#']['LETTER']['0']['#']);
+                        $DB->insert_record('grade_letters', $dbrec);
                     }
                 }
             }
         }
 
-        foreach ($blockobjects as $blockobject) {
-            $content = $blockobject->decode_content_links($content,$restore);
-        }
-
-        return $content;
-    }
-
-
-    //This function read the xml file and store it data from the info zone in an object
-    function restore_read_xml_info ($xml_file) {
-
-        //We call the main read_xml function, with $todo = INFO
-        $info = restore_read_xml ($xml_file,"INFO",false);
-
-        return $info;
-    }
+    /// Process grade items and grades
+        if ($status) {
+            if (!defined('RESTORE_SILENTLY')) {
+                echo '<li>'.get_string('gradeitems','grades').'</li>';
+            }
+            $counter = 0;
 
-    //This function read the xml file and store it data from the course header zone in an object
-    function restore_read_xml_course_header ($xml_file) {
+            //Fetch recordset_size records in each iteration
+            $recs = $DB->get_records("backup_ids", array('table_name'=>'grade_items', 'backup_code'=>$restore->backup_unique_code),
+                                        "id", // restore in the backup order
+                                        "old_id");
 
-        //We call the main read_xml function, with $todo = COURSE_HEADER
-        $info = restore_read_xml ($xml_file,"COURSE_HEADER",false);
+            if ($recs) {
+                foreach ($recs as $rec) {
+                    //Get the full record from backup_ids
+                    $data = backup_getid($restore->backup_unique_code,'grade_items',$rec->old_id);
+                    if ($data) {
+                        $info = $data->info;
 
-        return $info;
-    }
+                        // first find out if category or normal item
+                        $itemtype =  backup_todb($info['GRADE_ITEM']['#']['ITEMTYPE']['0']['#'], false);
+                        if ($itemtype == 'course' or $itemtype == 'category') {
+                            if (!$restoreall or $importing) {
+                                continue;
+                            }
 
-    //This function read the xml file and store its data from the blocks in a object
-    function restore_read_xml_blocks ($restore, $xml_file) {
+                            $oldcat = backup_todb($info['GRADE_ITEM']['#']['ITEMINSTANCE']['0']['#'], false);
+                            if (!$cdata = backup_getid($restore->backup_unique_code,'grade_categories',$oldcat)) {
+                                continue;
+                            }
+                            $cinfo = $cdata->info;
+                            unset($cdata);
+                            if ($itemtype == 'course') {
 
-        //We call the main read_xml function, with $todo = BLOCKS
-        $info = restore_read_xml ($xml_file,'BLOCKS',$restore);
+                                $course_category->fullname            = backup_todb($cinfo['GRADE_CATEGORY']['#']['FULLNAME']['0']['#'], false);
+                                $course_category->aggregation         = backup_todb($cinfo['GRADE_CATEGORY']['#']['AGGREGATION']['0']['#'], false);
+                                $course_category->keephigh            = backup_todb($cinfo['GRADE_CATEGORY']['#']['KEEPHIGH']['0']['#'], false);
+                                $course_category->droplow             = backup_todb($cinfo['GRADE_CATEGORY']['#']['DROPLOW']['0']['#'], false);
+                                $course_category->aggregateonlygraded = backup_todb($cinfo['GRADE_CATEGORY']['#']['AGGREGATEONLYGRADED']['0']['#'], false);
+                                $course_category->aggregateoutcomes   = backup_todb($cinfo['GRADE_CATEGORY']['#']['AGGREGATEOUTCOMES']['0']['#'], false);
+                                $course_category->aggregatesubcats    = backup_todb($cinfo['GRADE_CATEGORY']['#']['AGGREGATESUBCATS']['0']['#'], false);
+                                $course_category->timecreated         = backup_todb($cinfo['GRADE_CATEGORY']['#']['TIMECREATED']['0']['#'], false);
+                                $course_category->update('restore');
 
-        return $info;
-    }
+                                $status = backup_putid($restore->backup_unique_code,'grade_categories',$oldcat,$course_category->id) && $status;
+                                $cached_categories[$oldcat] = $course_category;
+                                $grade_item = $course_category->get_grade_item();
 
-    //This function read the xml file and store its data from the sections in a object
-    function restore_read_xml_sections ($xml_file) {
+                            } else {
+                                $oldparent = backup_todb($cinfo['GRADE_CATEGORY']['#']['PARENT']['0']['#'], false);
+                                if (empty($cached_categories[$oldparent])) {
+                                    debugging('parent not found '.$oldparent);
+                                    continue; // parent not found, sorry
+                                }
+                                $grade_category = new grade_category();
+                                $grade_category->courseid            = $restore->course_id;
+                                $grade_category->parent              = $cached_categories[$oldparent]->id;
+                                $grade_category->fullname            = backup_todb($cinfo['GRADE_CATEGORY']['#']['FULLNAME']['0']['#'], false);
+                                $grade_category->aggregation         = backup_todb($cinfo['GRADE_CATEGORY']['#']['AGGREGATION']['0']['#'], false);
+                                $grade_category->keephigh            = backup_todb($cinfo['GRADE_CATEGORY']['#']['KEEPHIGH']['0']['#'], false);
+                                $grade_category->droplow             = backup_todb($cinfo['GRADE_CATEGORY']['#']['DROPLOW']['0']['#'], false);
+                                $grade_category->aggregateonlygraded = backup_todb($cinfo['GRADE_CATEGORY']['#']['AGGREGATEONLYGRADED']['0']['#'], false);
+                                $grade_category->aggregateoutcomes   = backup_todb($cinfo['GRADE_CATEGORY']['#']['AGGREGATEOUTCOMES']['0']['#'], false);
+                                $grade_category->aggregatesubcats    = backup_todb($cinfo['GRADE_CATEGORY']['#']['AGGREGATESUBCATS']['0']['#'], false);
+                                $grade_category->timecreated         = backup_todb($cinfo['GRADE_CATEGORY']['#']['TIMECREATED']['0']['#'], false);
+                                $grade_category->insert('restore');
 
-        //We call the main read_xml function, with $todo = SECTIONS
-        $info = restore_read_xml ($xml_file,"SECTIONS",false);
+                                $status = backup_putid($restore->backup_unique_code,'grade_categories',$oldcat,$grade_category->id) && $status;
+                                $cached_categories[$oldcat] = $grade_category;
+                                $grade_item = $grade_category->get_grade_item(); // creates grade_item too
+                            }
+                            unset($cinfo);
 
-        return $info;
-    }
+                            $idnumber = backup_todb($info['GRADE_ITEM']['#']['IDNUMBER']['0']['#'], false);
+                            if (grade_verify_idnumber($idnumber, $restore->course_id)) {
+                                $grade_item->idnumber    = $idnumber;
+                            }
 
-    //This function read the xml file and store its data from the course format in an object
-    function restore_read_xml_formatdata ($xml_file) {
-
-        //We call the main read_xml function, with $todo = FORMATDATA
-        $info = restore_read_xml ($xml_file,'FORMATDATA',false);
-
-        return $info;
-    }
-
-    //This function read the xml file and store its data from the metacourse in a object
-    function restore_read_xml_metacourse ($xml_file) {
-
-        //We call the main read_xml function, with $todo = METACOURSE
-        $info = restore_read_xml ($xml_file,"METACOURSE",false);
-
-        return $info;
-    }
-
-    //This function read the xml file and store its data from the gradebook in a object
-    function restore_read_xml_gradebook ($restore, $xml_file) {
-
-        //We call the main read_xml function, with $todo = GRADEBOOK
-        $info = restore_read_xml ($xml_file,"GRADEBOOK",$restore);
-
-        return $info;
-    }
-
-    //This function read the xml file and store its data from the users in
-    //backup_ids->info db (and user's id in $info)
-    function restore_read_xml_users ($restore,$xml_file) {
-
-        //We call the main read_xml function, with $todo = USERS
-        $info = restore_read_xml ($xml_file,"USERS",$restore);
-
-        return $info;
-    }
-
-    //This function read the xml file and store its data from the messages in
-    //backup_ids->message backup_ids->message_read and backup_ids->contact and db (and their counters in info)
-    function restore_read_xml_messages ($restore,$xml_file) {
-
-        //We call the main read_xml function, with $todo = MESSAGES
-        $info = restore_read_xml ($xml_file,"MESSAGES",$restore);
-
-        return $info;
-    }
-
-    //This function read the xml file and store its data from the blogs in
-    //backup_ids->blog and backup_ids->blog_tag and db (and their counters in info)
-    function restore_read_xml_blogs ($restore,$xml_file) {
-
-        //We call the main read_xml function, with $todo = BLOGS
-        $info = restore_read_xml ($xml_file,"BLOGS",$restore);
-
-        return $info;
-    }
-
-
-    //This function read the xml file and store its data from the questions in
-    //backup_ids->info db (and category's id in $info)
-    function restore_read_xml_questions ($restore,$xml_file) {
-
-        //We call the main read_xml function, with $todo = QUESTIONS
-        $info = restore_read_xml ($xml_file,"QUESTIONS",$restore);
-
-        return $info;
-    }
-
-    //This function read the xml file and store its data from the scales in
-    //backup_ids->info db (and scale's id in $info)
-    function restore_read_xml_scales ($restore,$xml_file) {
-
-        //We call the main read_xml function, with $todo = SCALES
-        $info = restore_read_xml ($xml_file,"SCALES",$restore);
-
-        return $info;
-    }
-
-    //This function read the xml file and store its data from the groups in
-    //backup_ids->info db (and group's id in $info)
-    function restore_read_xml_groups ($restore,$xml_file) {
-
-        //We call the main read_xml function, with $todo = GROUPS
-        $info = restore_read_xml ($xml_file,"GROUPS",$restore);
+                            $grade_item->itemname        = backup_todb($info['GRADE_ITEM']['#']['ITEMNAME']['0']['#'], false);
+                            $grade_item->iteminfo        = backup_todb($info['GRADE_ITEM']['#']['ITEMINFO']['0']['#'], false);
+                            $grade_item->gradetype       = backup_todb($info['GRADE_ITEM']['#']['GRADETYPE']['0']['#'], false);
+                            $grade_item->calculation     = backup_todb($info['GRADE_ITEM']['#']['CALCULATION']['0']['#'], false);
+                            $grade_item->grademax        = backup_todb($info['GRADE_ITEM']['#']['GRADEMAX']['0']['#'], false);
+                            $grade_item->grademin        = backup_todb($info['GRADE_ITEM']['#']['GRADEMIN']['0']['#'], false);
+                            $grade_item->gradepass       = backup_todb($info['GRADE_ITEM']['#']['GRADEPASS']['0']['#'], false);
+                            $grade_item->multfactor      = backup_todb($info['GRADE_ITEM']['#']['MULTFACTOR']['0']['#'], false);
+                            $grade_item->plusfactor      = backup_todb($info['GRADE_ITEM']['#']['PLUSFACTOR']['0']['#'], false);
+                            $grade_item->aggregationcoef = backup_todb($info['GRADE_ITEM']['#']['AGGREGATIONCOEF']['0']['#'], false);
+                            $grade_item->display         = backup_todb($info['GRADE_ITEM']['#']['DISPLAY']['0']['#'], false);
+                            $grade_item->decimals        = backup_todb($info['GRADE_ITEM']['#']['DECIMALS']['0']['#'], false);
+                            $grade_item->hidden          = backup_todb($info['GRADE_ITEM']['#']['HIDDEN']['0']['#'], false);
+                            $grade_item->locked          = backup_todb($info['GRADE_ITEM']['#']['LOCKED']['0']['#'], false);
+                            $grade_item->locktime        = backup_todb($info['GRADE_ITEM']['#']['LOCKTIME']['0']['#'], false);
+                            $grade_item->timecreated     = backup_todb($info['GRADE_ITEM']['#']['TIMECREATED']['0']['#'], false);
 
-        return $info;
-    }
+                            if (backup_todb($info['GRADE_ITEM']['#']['SCALEID']['0']['#'], false)) {
+                                $scale = backup_getid($restore->backup_unique_code,"scale",backup_todb($info['GRADE_ITEM']['#']['SCALEID']['0']['#'], false));
+                                $grade_item->scaleid     = $scale->new_id;
+                            }
 
-    //This function read the xml file and store its data from the groupings in
-    //backup_ids->info db (and grouping's id in $info)
-    function restore_read_xml_groupings ($restore,$xml_file) {
+                            if  (backup_todb($info['GRADE_ITEM']['#']['OUTCOMEID']['0']['#'], false)) {
+                                $outcome = backup_getid($restore->backup_unique_code,"grade_outcomes",backup_todb($info['GRADE_ITEM']['#']['OUTCOMEID']['0']['#'], false));
+                                $grade_item->outcomeid   = $outcome->new_id;
+                            }
 
-        //We call the main read_xml function, with $todo = GROUPINGS
-        $info = restore_read_xml ($xml_file,"GROUPINGS",$restore);
+                            $grade_item->update('restore');
+                            $status = backup_putid($restore->backup_unique_code,"grade_items", $rec->old_id, $grade_item->id) && $status;
 
-        return $info;
-    }
+                        } else {
+                            if ($itemtype != 'mod' and (!$restoreall or $importing)) {
+                                // not extra gradebook stuff if restoring individual activities or something already there
+                                continue;
+                            }
 
-    //This function read the xml file and store its data from the groupings in
-    //backup_ids->info db (and grouping's id in $info)
-    function restore_read_xml_groupings_groups ($restore,$xml_file) {
+                            $dbrec = new object();
 
-        //We call the main read_xml function, with $todo = GROUPINGS
-        $info = restore_read_xml ($xml_file,"GROUPINGSGROUPS",$restore);
+                            $dbrec->courseid      = $restore->course_id;
+                            $dbrec->itemtype      = backup_todb($info['GRADE_ITEM']['#']['ITEMTYPE']['0']['#'], false);
+                            $dbrec->itemmodule    = backup_todb($info['GRADE_ITEM']['#']['ITEMMODULE']['0']['#'], false);
 
-        return $info;
-    }
+                            if ($itemtype == 'mod') {
+                                // iteminstance should point to new mod
+                                $olditeminstance = backup_todb($info['GRADE_ITEM']['#']['ITEMINSTANCE']['0']['#'], false);
+                                $mod = backup_getid($restore->backup_unique_code,$dbrec->itemmodule, $olditeminstance);
+                                $dbrec->iteminstance = $mod->new_id;
+                                if (!$cm = get_coursemodule_from_instance($dbrec->itemmodule, $mod->new_id)) {
+                                    // item not restored - no item
+                                    continue;
+                                }
+                                // keep in sync with activity idnumber
+                                $dbrec->idnumber = $cm->idnumber;
 
-    //This function read the xml file and store its data from the events (course) in
-    //backup_ids->info db (and event's id in $info)
-    function restore_read_xml_events ($restore,$xml_file) {
+                            } else {
+                                $idnumber = backup_todb($info['GRADE_ITEM']['#']['IDNUMBER']['0']['#'], false);
 
-        //We call the main read_xml function, with $todo = EVENTS
-        $info = restore_read_xml ($xml_file,"EVENTS",$restore);
+                                if (grade_verify_idnumber($idnumber, $restore->course_id)) {
+                                    //make sure the new idnumber is unique
+                                    $dbrec->idnumber  = $idnumber;
+                                }
+                            }
 
-        return $info;
-    }
+                            $dbrec->itemname        = backup_todb($info['GRADE_ITEM']['#']['ITEMNAME']['0']['#'], false);
+                            $dbrec->itemtype        = backup_todb($info['GRADE_ITEM']['#']['ITEMTYPE']['0']['#'], false);
+                            $dbrec->itemmodule      = backup_todb($info['GRADE_ITEM']['#']['ITEMMODULE']['0']['#'], false);
+                            $dbrec->itemnumber      = backup_todb($info['GRADE_ITEM']['#']['ITEMNUMBER']['0']['#'], false);
+                            $dbrec->iteminfo        = backup_todb($info['GRADE_ITEM']['#']['ITEMINFO']['0']['#'], false);
+                            $dbrec->gradetype       = backup_todb($info['GRADE_ITEM']['#']['GRADETYPE']['0']['#'], false);
+                            $dbrec->calculation     = backup_todb($info['GRADE_ITEM']['#']['CALCULATION']['0']['#'], false);
+                            $dbrec->grademax        = backup_todb($info['GRADE_ITEM']['#']['GRADEMAX']['0']['#'], false);
+                            $dbrec->grademin        = backup_todb($info['GRADE_ITEM']['#']['GRADEMIN']['0']['#'], false);
+                            $dbrec->gradepass       = backup_todb($info['GRADE_ITEM']['#']['GRADEPASS']['0']['#'], false);
+                            $dbrec->multfactor      = backup_todb($info['GRADE_ITEM']['#']['MULTFACTOR']['0']['#'], false);
+                            $dbrec->plusfactor      = backup_todb($info['GRADE_ITEM']['#']['PLUSFACTOR']['0']['#'], false);
+                            $dbrec->aggregationcoef = backup_todb($info['GRADE_ITEM']['#']['AGGREGATIONCOEF']['0']['#'], false);
+                            $dbrec->display         = backup_todb($info['GRADE_ITEM']['#']['DISPLAY']['0']['#'], false);
+                            $dbrec->decimals        = backup_todb($info['GRADE_ITEM']['#']['DECIMALS']['0']['#'], false);
+                            $dbrec->hidden          = backup_todb($info['GRADE_ITEM']['#']['HIDDEN']['0']['#'], false);
+                            $dbrec->locked          = backup_todb($info['GRADE_ITEM']['#']['LOCKED']['0']['#'], false);
+                            $dbrec->locktime        = backup_todb($info['GRADE_ITEM']['#']['LOCKTIME']['0']['#'], false);
+                            $dbrec->timecreated     = backup_todb($info['GRADE_ITEM']['#']['TIMECREATED']['0']['#'], false);
 
-    //This function read the xml file and store its data from the modules in
-    //backup_ids->info
-    function restore_read_xml_modules ($restore,$xml_file) {
+                            if (backup_todb($info['GRADE_ITEM']['#']['SCALEID']['0']['#'], false)) {
+                                $scale = backup_getid($restore->backup_unique_code,"scale",backup_todb($info['GRADE_ITEM']['#']['SCALEID']['0']['#'], false));
+                                $dbrec->scaleid = $scale->new_id;
+                            }
 
-        //We call the main read_xml function, with $todo = MODULES
-        $info = restore_read_xml ($xml_file,"MODULES",$restore);
+                            if  (backup_todb($info['GRADE_ITEM']['#']['OUTCOMEID']['0']['#'])) {
+                                $oldoutcome = backup_todb($info['GRADE_ITEM']['#']['OUTCOMEID']['0']['#']);
+                                if (empty($outcomes[$oldoutcome])) {
+                                    continue; // error!
+                                }
+                                if (empty($outcomes[$oldoutcome]->id)) {
+                                    $outcomes[$oldoutcome]->insert('restore');
+                                    $outcomes[$oldoutcome]->use_in($restore->course_id);
+                                    backup_putid($restore->backup_unique_code, "grade_outcomes", $oldoutcome, $outcomes[$oldoutcome]->id);
+                                }
+                                $dbrec->outcomeid = $outcomes[$oldoutcome]->id;
+                            }
 
-        return $info;
-    }
+                            $grade_item = new grade_item($dbrec, false);
+                            $grade_item->insert('restore');
+                            if ($restoreall) {
+                                // set original parent if restored
+                                $oldcat = $info['GRADE_ITEM']['#']['CATEGORYID']['0']['#'];
+                                if (!empty($cached_categories[$oldcat])) {
+                                    $grade_item->set_parent($cached_categories[$oldcat]->id);
+                                }
+                            }
+                            $status = backup_putid($restore->backup_unique_code,"grade_items", $rec->old_id, $grade_item->id) && $status;
+                        }
 
-    //This function read the xml file and store its data from the logs in
-    //backup_ids->info
-    function restore_read_xml_logs ($restore,$xml_file) {
+                        // no need to restore grades if user data is not selected or importing activities
+                        if ($importing
+                          or ($grade_item->itemtype == 'mod' and !restore_userdata_selected($restore,  $grade_item->itemmodule, $olditeminstance))) {
+                            // module instance not selected when restored using granular
+                            // skip this item
+                            continue;
+                        }
 
-        //We call the main read_xml function, with $todo = LOGS
-        $info = restore_read_xml ($xml_file,"LOGS",$restore);
+                        /// now, restore grade_grades
+                        if (!empty($info['GRADE_ITEM']['#']['GRADE_GRADES']['0']['#']['GRADE'])) {
+                            //Iterate over items
+                            foreach ($info['GRADE_ITEM']['#']['GRADE_GRADES']['0']['#']['GRADE'] as $g_info) {
 
-        return $info;
-    }
+                                $grade = new grade_grade();
+                                $grade->itemid         = $grade_item->id;
 
-    function restore_read_xml_roles ($xml_file) {
-        //We call the main read_xml function, with $todo = ROLES
-        $info = restore_read_xml ($xml_file,"ROLES",false);
+                                $olduser = backup_todb($g_info['#']['USERID']['0']['#'], false);
+                                $user = backup_getid($restore->backup_unique_code,"user",$olduser);
+                                $grade->userid         = $user->new_id;
 
-        return $info;
-    }
+                                $grade->rawgrade       = backup_todb($g_info['#']['RAWGRADE']['0']['#'], false);
+                                $grade->rawgrademax    = backup_todb($g_info['#']['RAWGRADEMAX']['0']['#'], false);
+                                $grade->rawgrademin    = backup_todb($g_info['#']['RAWGRADEMIN']['0']['#'], false);
+                                // need to find scaleid
+                                if (backup_todb($g_info['#']['RAWSCALEID']['0']['#'])) {
+                                    $scale = backup_getid($restore->backup_unique_code,"scale",backup_todb($g_info['#']['RAWSCALEID']['0']['#'], false));
+                                    $grade->rawscaleid = $scale->new_id;
+                                }
 
-    //This function prints the contents from the info parammeter passed
-    function restore_print_info ($info) {
+                                if (backup_todb($g_info['#']['USERMODIFIED']['0']['#'])) {
+                                    if ($modifier = backup_getid($restore->backup_unique_code,"user", backup_todb($g_info['#']['USERMODIFIED']['0']['#'], false))) {
+                                        $grade->usermodified = $modifier->new_id;
+                                    }
+                                }
 
-        global $CFG, $OUTPUT;
+                                $grade->finalgrade        = backup_todb($g_info['#']['FINALGRADE']['0']['#'], false);
+                                $grade->hidden            = backup_todb($g_info['#']['HIDDEN']['0']['#'], false);
+                                $grade->locked            = backup_todb($g_info['#']['LOCKED']['0']['#'], false);
+                                $grade->locktime          = backup_todb($g_info['#']['LOCKTIME']['0']['#'], false);
+                                $grade->exported          = backup_todb($g_info['#']['EXPORTED']['0']['#'], false);
+                                $grade->overridden        = backup_todb($g_info['#']['OVERRIDDEN']['0']['#'], false);
+                                $grade->excluded          = backup_todb($g_info['#']['EXCLUDED']['0']['#'], false);
+                                $grade->feedback          = backup_todb($g_info['#']['FEEDBACK']['0']['#'], false);
+                                $grade->feedbackformat    = backup_todb($g_info['#']['FEEDBACKFORMAT']['0']['#'], false);
+                                $grade->information       = backup_todb($g_info['#']['INFORMATION']['0']['#'], false);
+                                $grade->informationformat = backup_todb($g_info['#']['INFORMATIONFORMAT']['0']['#'], false);
+                                $grade->timecreated       = backup_todb($g_info['#']['TIMECREATED']['0']['#'], false);
+                                $grade->timemodified      = backup_todb($g_info['#']['TIMEMODIFIED']['0']['#'], false);
 
-        $status = true;
-        if ($info) {
-            $table = new html_table();
-            //This is tha align to every ingo table
-            $table->align = array ("right","left");
-            //This is the nowrap clause
-            $table->wrap = array ("","nowrap");
-            //The width
-            $table->width = "70%";
-            //Put interesting info in table
-            //The backup original name
-            $tab[0][0] = "<b>".get_string("backuporiginalname").":</b>";
-            $tab[0][1] = $info->backup_name;
-            //The moodle version
-            $tab[1][0] = "<b>".get_string("moodleversion").":</b>";
-            $tab[1][1] = $info->backup_moodle_release." (".$info->backup_moodle_version.")";
-            //The backup version
-            $tab[2][0] = "<b>".get_string("backupversion").":</b>";
-            $tab[2][1] = $info->backup_backup_release." (".$info->backup_backup_version.")";
-            //The backup date
-            $tab[3][0] = "<b>".get_string("backupdate").":</b>";
-            $tab[3][1] = userdate($info->backup_date);
-            //Is this the same Moodle install?
-            if (!empty($info->original_siteidentifier)) {
-                $tab[4][0] = "<b>".get_string("backupfromthissite").":</b>";
-                if (backup_is_same_site($info)) {
-                    $tab[4][1] = get_string('yes');
-                } else {
-                    $tab[4][1] = get_string('no');
-                }
-            }
-            //Print title
-            echo $OUTPUT->heading(get_string("backup").":");
-            $table->data = $tab;
-            //Print backup general info
-            echo html_writer::table($table);
-
-            if ($info->backup_backup_version <= 2005070500) {
-                 echo $OUTPUT->notification(get_string('backupnonisowarning'));  // Message informing that this backup may not work!
-            }
+                                $grade->insert('restore');
+                                backup_putid($restore->backup_unique_code,"grade_grades", backup_todb($g_info['#']['ID']['0']['#']), $grade->id);
 
-            //Now backup contents in another table
-            $tab = array();
-            //First mods info
-            $mods = $info->mods;
-            $elem = 0;
-            foreach ($mods as $key => $mod) {
-                $tab[$elem][0] = "<b>".get_string("modulenameplural",$key).":</b>";
-                if ($mod->backup == "false") {
-                    $tab[$elem][1] = get_string("notincluded");
-                } else {
-                    if ($mod->userinfo == "true") {
-                        $tab[$elem][1] = get_string("included")." ".get_string("withuserdata");
-                    } else {
-                        $tab[$elem][1] = get_string("included")." ".get_string("withoutuserdata");
-                    }
-                    if (isset($mod->instances) && is_array($mod->instances) && count($mod->instances)) {
-                        foreach ($mod->instances as $instance) {
-                            if ($instance->backup) {
-                                $elem++;
-                                $tab[$elem][0] = $instance->name;
-                                if ($instance->userinfo == 'true') {
-                                    $tab[$elem][1] = get_string("included")." ".get_string("withuserdata");
-                                } else {
-                                    $tab[$elem][1] = get_string("included")." ".get_string("withoutuserdata");
+                                $counter++;
+                                if ($counter % 20 == 0) {
+                                    if (!defined('RESTORE_SILENTLY')) {
+                                        echo ".";
+                                        if ($counter % 400 == 0) {
+                                            echo "<br />";
+                                        }
+                                    }
+                                    backup_flush(300);
                                 }
                             }
                         }
                     }
                 }
-                $elem++;
-            }
-            //Metacourse info
-            $tab[$elem][0] = "<b>".get_string("metacourse").":</b>";
-            if ($info->backup_metacourse == "true") {
-                $tab[$elem][1] = get_string("yes");
-            } else {
-                $tab[$elem][1] = get_string("no");
-            }
-            $elem++;
-            //Users info
-            $tab[$elem][0] = "<b>".get_string("users").":</b>";
-            $tab[$elem][1] = get_string($info->backup_users);
-            $elem++;
-            //Logs info
-            $tab[$elem][0] = "<b>".get_string("logs").":</b>";
-            if ($info->backup_logs == "true") {
-                $tab[$elem][1] = get_string("yes");
-            } else {
-                $tab[$elem][1] = get_string("no");
-            }
-            $elem++;
-            //User Files info
-            $tab[$elem][0] = "<b>".get_string("userfiles").":</b>";
-            if ($info->backup_user_files == "true") {
-                $tab[$elem][1] = get_string("yes");
-            } else {
-                $tab[$elem][1] = get_string("no");
-            }
-            $elem++;
-            //Course Files info
-            $tab[$elem][0] = "<b>".get_string("coursefiles").":</b>";
-            if ($info->backup_course_files == "true") {
-                $tab[$elem][1] = get_string("yes");
-            } else {
-                $tab[$elem][1] = get_string("no");
-            }
-            $elem++;
-            //site Files info
-            $tab[$elem][0] = "<b>".get_string("sitefiles").":</b>";
-            if (isset($info->backup_site_files) && $info->backup_site_files == "true") {
-                $tab[$elem][1] = get_string("yes");
-            } else {
-                $tab[$elem][1] = get_string("no");
-            }
-            $elem++;
-            //gradebook history info
-            $tab[$elem][0] = "<b>".get_string('gradebookhistories', 'grades').":</b>";
-            if (isset($info->gradebook_histories) && $info->gradebook_histories == "true") {
-                $tab[$elem][1] = get_string("yes");
-            } else {
-                $tab[$elem][1] = get_string("no");
-            }
-            $elem++;
-            //Messages info (only showed if present)
-            if ($info->backup_messages == 'true') {
-                $tab[$elem][0] = "<b>".get_string('messages','message').":</b>";
-                $tab[$elem][1] = get_string('yes');
-                $elem++;
-            } else {
-                //Do nothing
-            }
-            $elem++;
-            //Blogs info (only showed if present)
-            if (isset($info->backup_blogs) && $info->backup_blogs == 'true') {
-                $tab[$elem][0] = "<b>".get_string('blogs','blog').":</b>";
-                $tab[$elem][1] = get_string('yes');
-                $elem++;
-            } else {
-                //Do nothing
             }
-            $table->data = $tab;
-            //Print title
-            echo $OUTPUT->heading(get_string("backupdetails").":");
-            //Print backup general info
-            echo html_writer::table($table);
-        } else {
-            $status = false;
         }
 
-        return $status;
-    }
-
-    //This function prints the contents from the course_header parammeter passed
-    function restore_print_course_header ($course_header) {
-        global $OUTPUT;
-        $status = true;
-        if ($course_header) {
-            $table = new html_table();
-            //This is tha align to every ingo table
-            $table->align = array ("right","left");
-            //The width
-            $table->width = "70%";
-            //Put interesting course header in table
-            //The course name
-            $tab[0][0] = "<b>".get_string("name").":</b>";
-            $tab[0][1] = $course_header->course_fullname." (".$course_header->course_shortname.")";
-            //The course summary
-            $tab[1][0] = "<b>".get_string("summary").":</b>";
-            $tab[1][1] = $course_header->course_summary;
-            $table->data = $tab;
-            //Print title
-            echo $OUTPUT->heading(get_string("course").":");
-            //Print backup course header info
-            echo html_writer::table($table);
-        } else {
-            $status = false;
+    /// add outcomes that are not used when doing full restore
+        if ($status and $restoreall) {
+            foreach ($outcomes as $oldoutcome=>$grade_outcome) {
+                if (empty($grade_outcome->id)) {
+                    $grade_outcome->insert('restore');
+                    $grade_outcome->use_in($restore->course_id);
+                    backup_putid($restore->backup_unique_code, "grade_outcomes", $oldoutcome, $grade_outcome->id);
+                }
+            }
         }
-        return $status;
-    }
-
-   /**
-    * Given one user object (from backup file), perform all the neccesary
-    * checks is order to decide how that user will be handled on restore.
-    *
-    * Note the function requires $user->mnethostid to be already calculated
-    * so it's caller responsibility to set it
-    *
-    * This function is used both by @restore_precheck_users() and
-    * @restore_create_users() to get consistent results in both places
-    *
-    * It returns:
-    *   - one user object (from DB), if match has been found and user will be remapped
-    *   - boolean true if the user needs to be created
-    *   - boolean false if some conflict happened and the user cannot be handled
-    *
-    * Each test is responsible for returning its results and interrupt
-    * execution. At the end, boolean true (user needs to be created) will be
-    * returned if no test has interrupted that.
-    *
-    * Here it's the logic applied, keep it updated:
-    *
-    *  If restoring users from same site backup:
-    *      1A - Normal check: If match by id and username and mnethost  => ok, return target user
-    *      1B - Handle users deleted in DB and "alive" in backup file:
-    *           If match by id and mnethost and user is deleted in DB and
-    *           (match by username LIKE 'backup_email.%' or by non empty email = md5(username)) => ok, return target user
-    *      1C - Handle users deleted in backup file and "alive" in DB:
-    *           If match by id and mnethost and user is deleted in backup file
-    *           and match by email = email_without_time(backup_email) => ok, return target user
-    *      1D - Conflict: If match by username and mnethost and doesn't match by id => conflict, return false
-    *      1E - None of the above, return true => User needs to be created
-    *
-    *  if restoring from another site backup (cannot match by id here, replace it by email/firstaccess combination):
-    *      2A - Normal check: If match by username and mnethost and (email or non-zero firstaccess) => ok, return target user
-    *      2B - Handle users deleted in DB and "alive" in backup file:
-    *           2B1 - If match by mnethost and user is deleted in DB and not empty email = md5(username) and
-    *                 (username LIKE 'backup_email.%' or non-zero firstaccess) => ok, return target user
-    *           2B2 - If match by mnethost and user is deleted in DB and
-    *                 username LIKE 'backup_email.%' and non-zero firstaccess) => ok, return target user
-    *                 (to cover situations were md5(username) wasn't implemented on delete we requiere both)
-    *      2C - Handle users deleted in backup file and "alive" in DB:
-    *           If match mnethost and user is deleted in backup file
-    *           and by email = email_without_time(backup_email) and non-zero firstaccess=> ok, return target user
-    *      2D - Conflict: If match by username and mnethost and not by (email or non-zero firstaccess) => conflict, return false
-    *      2E - None of the above, return true => User needs to be created
-    *
-    * Note: for DB deleted users email is stored in username field, hence we
-    *       are looking there for emails. See delete_user()
-    * Note: for DB deleted users md5(username) is stored *sometimes* in the email field,
-    *       hence we are looking there for usernames if not empty. See delete_user()
-    */
-    function restore_check_user($restore, $user) {
-        global $CFG, $DB;
 
-        // Verify mnethostid is set, return error if not
-        // it's parent responsibility to define that before
-        // arriving here
-        if (empty($user->mnethostid)) {
-            debugging("restore_check_user() wrong use, mnethostid not set for user $user->username", DEBUG_DEVELOPER);
-            return false;
-        }
 
-        // Handle checks from same site backups
-        if (backup_is_same_site($restore) && empty($CFG->forcedifferentsitecheckingusersonrestore)) {
+        if ($status and !$importing and $restore_histories) {
+            /// following code is very inefficient
 
-            // 1A - If match by id and username and mnethost => ok, return target user
-            if ($rec = $DB->get_record('user', array('id'=>$user->id, 'username'=>$user->username, 'mnethostid'=>$user->mnethostid))) {
-                return $rec; // Matching user found, return it
-            }
+            $gchcount = $DB->count_records('backup_ids', array('backup_code'=>$restore->backup_unique_code, 'table_name'=>'grade_categories_history'));
+            $gghcount = $DB->count_records('backup_ids', array('backup_code'=>$restore->backup_unique_code, 'table_name'=>'grade_grades_history'));
+            $gihcount = $DB->count_records('backup_ids', array('backup_code'=>$restore->backup_unique_code, 'table_name'=>'grade_items_history'));
+            $gohcount = $DB->count_records('backup_ids', array('backup_code'=>$restore->backup_unique_code, 'table_name'=>'grade_outcomes_history'));
 
-            // 1B - Handle users deleted in DB and "alive" in backup file
-            // Note: for DB deleted users email is stored in username field, hence we
-            //       are looking there for emails. See delete_user()
-            // Note: for DB deleted users md5(username) is stored *sometimes* in the email field,
-            //       hence we are looking there for usernames if not empty. See delete_user()
-            // If match by id and mnethost and user is deleted in DB and
-            // match by username LIKE 'backup_email.%' or by non empty email = md5(username) => ok, return target user
-            if ($rec = $DB->get_record_sql("SELECT *
-                                              FROM {user} u
-                                             WHERE id = ?
-                                               AND mnethostid = ?
-                                               AND deleted = 1
-                                               AND (
-                                                       username LIKE ?
-                                                    OR (
-                                                           ".$DB->sql_isnotempty('user', 'email', false, false)."
-                                                       AND email = ?
-                                                       )
-                                                   )",
-                                           array($user->id, $user->mnethostid, $user->email.'.%', md5($user->username)))) {
-                return $rec; // Matching user, deleted in DB found, return it
-            }
+            // Number of records to get in every chunk
+            $recordset_size = 2;
 
-            // 1C - Handle users deleted in backup file and "alive" in DB
-            // If match by id and mnethost and user is deleted in backup file
-            // and match by email = email_without_time(backup_email) => ok, return target user
-            if ($user->deleted) {
-                // Note: for DB deleted users email is stored in username field, hence we
-                //       are looking there for emails. See delete_user()
-                // Trim time() from email
-                $trimemail = preg_replace('/(.*?)\.[0-9]+.?$/', '\\1', $user->username);
-                if ($rec = $DB->get_record_sql("SELECT *
-                                                  FROM {user} u
-                                                 WHERE id = ?
-                                                   AND mnethostid = ?
-                                                   AND email = ?",
-                                               array($user->id, $user->mnethostid, $trimemail))) {
-                    return $rec; // Matching user, deleted in backup file found, return it
+            // process histories
+            if ($gchcount && $status) {
+                if (!defined('RESTORE_SILENTLY')) {
+                    echo '<li>'.get_string('gradecategoryhistory','grades').'</li>';
                 }
-            }
+                $counter = 0;
+                while ($counter < $gchcount) {
+                    //Fetch recordset_size records in each iteration
+                    $recs = $DB->get_records("backup_ids",array('table_name'=>'grade_categories_history', 'backup_code'=>$restore->backup_unique_code),
+                                                "old_id",
+                                                "old_id",
+                                                $counter,
+                                                $recordset_size);
+                    if ($recs) {
+                        foreach ($recs as $rec) {
+                            //Get the full record from backup_ids
+                            $data = backup_getid($restore->backup_unique_code,'grade_categories_history',$rec->old_id);
+                            if ($data) {
+                                //Now get completed xmlized object
+                                $info = $data->info;
+                                //traverse_xmlize($info);                            //Debug
+                                //print_object ($GLOBALS['traverse_array']);         //Debug
+                                //$GLOBALS['traverse_array']="";                     //Debug
 
-            // 1D - If match by username and mnethost and doesn't match by id => conflict, return false
-            if ($rec = $DB->get_record('user', array('username'=>$user->username, 'mnethostid'=>$user->mnethostid))) {
-                if ($user->id != $rec->id) {
-                    return false; // Conflict, username already exists and belongs to another id
-                }
-            }
+                                $oldobj = backup_getid($restore->backup_unique_code,"grade_categories", backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['OLDID']['0']['#']));
+                                if (empty($oldobj->new_id)) {
+                                    // if the old object is not being restored, can't restoring its history
+                                    $counter++;
+                                    continue;
+                                }
+                                $dbrec->oldid = $oldobj->new_id;
+                                $dbrec->action = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['ACTION']['0']['#']);
+                                $dbrec->source = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['SOURCE']['0']['#']);
+                                $dbrec->timemodified = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['TIMEMODIFIED']['0']['#']);
 
-        // Handle checks from different site backups
-        } else {
+                                // loggeduser might not be restored, e.g. admin
+                                if ($oldobj = backup_getid($restore->backup_unique_code,"user", backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['LOGGEDUSER']['0']['#']))) {
+                                    $dbrec->loggeduser = $oldobj->new_id;
+                                }
 
-            // 2A - If match by username and mnethost and
-            //     (email or non-zero firstaccess) => ok, return target user
-            if ($rec = $DB->get_record_sql("SELECT *
-                                              FROM {user} u
-                                             WHERE username = ?
-                                               AND mnethostid = ?
-                                               AND (
-                                                       email = ?
-                                                    OR (
-                                                           firstaccess != 0
-                                                       AND firstaccess = ?
-                                                       )
-                                                   )",
-                                           array($user->username, $user->mnethostid, $user->email, $user->firstaccess))) {
-                return $rec; // Matching user found, return it
-            }
+                                // this item might not have a parent at all, do not skip it if no parent is specified
+                                if (backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['PARENT']['0']['#'])) {
+                                    $oldobj = backup_getid($restore->backup_unique_code,"grade_categories", backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['PARENT']['0']['#']));
+                                    if (empty($oldobj->new_id)) {
+                                        // if the parent category not restored
+                                        $counter++;
+                                        continue;
+                                    }
+                                }
+                                $dbrec->parent = $oldobj->new_id;
+                                $dbrec->depth = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['DEPTH']['0']['#']);
+                                // path needs to be rebuilt
+                                if ($path = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['PATH']['0']['#'])) {
+                                // to preserve the path and make it work, we need to replace the categories one by one
+                                // we first get the list of categories in current path
+                                    if ($paths = explode("/", $path)) {
+                                        $newpath = '';
+                                        foreach ($paths as $catid) {
+                                            if ($catid) {
+                                                // find the new corresponding path
+                                                $oldpath = backup_getid($restore->backup_unique_code,"grade_categories", $catid);
+                                                $newpath .= "/$oldpath->new_id";
+                                            }
+                                        }
+                                        $dbrec->path = $newpath;
+                                    }
+                                }
+                                $dbrec->fullname = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['FULLNAME']['0']['#']);
+                                $dbrec->aggregation = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['AGGRETGATION']['0']['#']);
+                                $dbrec->keephigh = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['KEEPHIGH']['0']['#']);
+                                $dbrec->droplow = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['DROPLOW']['0']['#']);
 
-            // 2B - Handle users deleted in DB and "alive" in backup file
-            // Note: for DB deleted users email is stored in username field, hence we
-            //       are looking there for emails. See delete_user()
-            // Note: for DB deleted users md5(username) is stored *sometimes* in the email field,
-            //       hence we are looking there for usernames if not empty. See delete_user()
-            // 2B1 - If match by mnethost and user is deleted in DB and not empty email = md5(username) and
-            //       (by username LIKE 'backup_email.%' or non-zero firstaccess) => ok, return target user
-            if ($rec = $DB->get_record_sql("SELECT *
-                                              FROM {user} u
-                                             WHERE mnethostid = ?
-                                               AND deleted = 1
-                                               AND ".$DB->sql_isnotempty('user', 'email', false, false)."
-                                               AND email = ?
-                                               AND (
-                                                       username LIKE ?
-                                                    OR (
-                                                           firstaccess != 0
-                                                       AND firstaccess = ?
-                                                       )
-                                                   )",
-                                           array($user->mnethostid, md5($user->username), $user->email.'.%', $user->firstaccess))) {
-                return $rec; // Matching user found, return it
-            }
+                                $dbrec->aggregateonlygraded = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['AGGREGATEONLYGRADED']['0']['#']);
+                                $dbrec->aggregateoutcomes = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['AGGREGATEOUTCOMES']['0']['#']);
+                                $dbrec->aggregatesubcats = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['AGGREGATESUBCATS']['0']['#']);
 
-            // 2B2 - If match by mnethost and user is deleted in DB and
-            //       username LIKE 'backup_email.%' and non-zero firstaccess) => ok, return target user
-            //       (this covers situations where md5(username) wasn't being stored so we require both
-            //        the email & non-zero firstaccess to match)
-            if ($rec = $DB->get_record_sql("SELECT *
-                                              FROM {user} u
-                                             WHERE mnethostid = ?
-                                               AND deleted = 1
-                                               AND username LIKE ?
-                                               AND firstaccess != 0
-                                               AND firstaccess = ?",
-                                           array($user->mnethostid, $user->email.'.%', $user->firstaccess))) {
-                return $rec; // Matching user found, return it
-            }
+                                $dbrec->courseid = $restore->course_id;
+                                $DB->insert_record('grade_categories_history', $dbrec);
+                                unset($dbrec);
 
-            // 2C - Handle users deleted in backup file and "alive" in DB
-            // If match mnethost and user is deleted in backup file
-            // and match by email = email_without_time(backup_email) and non-zero firstaccess=> ok, return target user
-            if ($user->deleted) {
-                // Note: for DB deleted users email is stored in username field, hence we
-                //       are looking there for emails. See delete_user()
-                // Trim time() from email
-                $trimemail = preg_replace('/(.*?)\.[0-9]+.?$/', '\\1', $user->username);
-                if ($rec = $DB->get_record_sql("SELECT *
-                                                  FROM {user} u
-                                                 WHERE mnethostid = ?
-                                                   AND email = ?
-                                                   AND firstaccess != 0
-                                                   AND firstaccess = ?",
-                                               array($user->mnethostid, $trimemail, $user->firstaccess))) {
-                    return $rec; // Matching user, deleted in backup file found, return it
+                            }
+                            //Increment counters
+                            $counter++;
+                            //Do some output
+                            if ($counter % 1 == 0) {
+                                if (!defined('RESTORE_SILENTLY')) {
+                                    echo ".";
+                                    if ($counter % 20 == 0) {
+                                        echo "<br />";
+                                    }
+                                }
+                                backup_flush(300);
+                            }
+                        }
+                    }
                 }
             }
 
-            // 2D - If match by username and mnethost and not by (email or non-zero firstaccess) => conflict, return false
-            if ($rec = $DB->get_record_sql("SELECT *
-                                              FROM {user} u
-                                             WHERE username = ?
-                                               AND mnethostid = ?
-                                           AND NOT (
-                                                       email = ?
-                                                    OR (
-                                                           firstaccess != 0
-                                                       AND firstaccess = ?
-                                                       )
-                                                   )",
-                                           array($user->username, $user->mnethostid, $user->email, $user->firstaccess))) {
-                return false; // Conflict, username/mnethostid already exist and belong to another user (by email/firstaccess)
-            }
-        }
-
-        // Arrived here, return true as the user will need to be created and no
-        // conflicts have been found in the logic above. This covers:
-        // 1E - else => user needs to be created, return true
-        // 2E - else => user needs to be created, return true
-        return true;
-    }
-
-   /**
-    * For all the users being restored, check if they are going to cause problems
-    * before executing the restore process itself, detecting situations like:
-    *   - conflicts preventing restore to continue - provided by @restore_check_user()
-    *   - prevent creation of users if not allowed - check some global settings/caps
-    */
-    function restore_precheck_users($xml_file, $restore, &$problems) {
-        global $CFG, $DB;
-
-        $status = true; // Init $status
-
-        // We aren't restoring users, nothing to check, allow continue
-        if ($restore->users == 2) {
-            return true;
-        }
-
-        // Get array of users from xml file and load them in backup_ids table
-        if (!$info = restore_read_xml_users($restore,$xml_file)) {
-            return true; // No users, nothing to check, allow continue
-        }
+            // process histories
+            if ($gghcount && $status) {
+                if (!defined('RESTORE_SILENTLY')) {
+                    echo '<li>'.get_string('gradegradeshistory','grades').'</li>';
+                }
+                $counter = 0;
+                while ($counter < $gghcount) {
+                    //Fetch recordset_size records in each iteration
+                    $recs = $DB->get_records("backup_ids", array('table_name'=>'grade_grades_history', 'backup_code'=>$restore->backup_unique_code),
+                                                "old_id",
+                                                "old_id",
+                                                $counter,
+                                                $recordset_size);
+                    if ($recs) {
+                        foreach ($recs as $rec) {
+                            //Get the full record from backup_ids
+                            $data = backup_getid($restore->backup_unique_code,'grade_grades_history',$rec->old_id);
+                            if ($data) {
+                                //Now get completed xmlized object
+                                $info = $data->info;
+                                //traverse_xmlize($info);                            //Debug
+                                //print_object ($GLOBALS['traverse_array']);         //Debug
+                                //$GLOBALS['traverse_array']="";                     //Debug
 
-        // We are going to map mnethostid, so load all the available ones
-        $mnethosts = $DB->get_records('mnet_host', array(), 'wwwroot', 'wwwroot, id');
+                                $oldobj = backup_getid($restore->backup_unique_code,"grade_grades", backup_todb($info['GRADE_GRADES_HISTORY']['#']['OLDID']['0']['#']));
+                                if (empty($oldobj->new_id)) {
+                                    // if the old object is not being restored, can't restoring its history
+                                    $counter++;
+                                    continue;
+                                }
+                                $dbrec->oldid = $oldobj->new_id;
+                                $dbrec->action = backup_todb($info['GRADE_GRADES_HISTORY']['#']['ACTION']['0']['#']);
+                                $dbrec->source = backup_todb($info['GRADE_GRADES_HISTORY']['#']['SOURCE']['0']['#']);
+                                $dbrec->timemodified = backup_todb($info['GRADE_GRADES_HISTORY']['#']['TIMEMODIFIED']['0']['#']);
+                                if ($oldobj = backup_getid($restore->backup_unique_code,"user", backup_todb($info['GRADE_GRADES_HISTORY']['#']['LOGGEDUSER']['0']['#']))) {
+                                    $dbrec->loggeduser = $oldobj->new_id;
+                                }
 
-        // Calculate the context we are going to use for capability checking
-        if (!empty($restore->course_id)) { // Know the target (existing) course, check capabilities there
-            $context = get_context_instance(CONTEXT_COURSE, $restore->course_id);
-        } else if (!empty($restore->restore_restorecatto)) { // Know the category, check capabilities there
-            $context = get_context_instance(CONTEXT_COURSECAT, $restore->restore_restorecatto);
-        } else { // Last resort, check capabilities at system level
-            $context = get_context_instance(CONTEXT_SYSTEM);
-        }
+                                $oldobj = backup_getid($restore->backup_unique_code,"grade_items", backup_todb($info['GRADE_GRADES_HISTORY']['#']['ITEMID']['0']['#']));
+                                $dbrec->itemid = $oldobj->new_id;
+                                if (empty($dbrec->itemid)) {
+                                    $counter++;
+                                    continue; // grade item not being restored
+                                }
+                                $oldobj = backup_getid($restore->backup_unique_code,"user", backup_todb($info['GRADE_GRADES_HISTORY']['#']['USERID']['0']['#']));
+                                $dbrec->userid = $oldobj->new_id;
+                                $dbrec->rawgrade = backup_todb($info['GRADE_GRADES_HISTORY']['#']['RAWGRADE']['0']['#']);
+                                $dbrec->rawgrademax = backup_todb($info['GRADE_GRADES_HISTORY']['#']['RAWGRADEMAX']['0']['#']);
+                                $dbrec->rawgrademin = backup_todb($info['GRADE_GRADES_HISTORY']['#']['RAWGRADEMIN']['0']['#']);
+                                if ($oldobj = backup_getid($restore->backup_unique_code,"user", backup_todb($info['GRADE_GRADES_HISTORY']['#']['USERMODIFIED']['0']['#']))) {
+                                    $dbrec->usermodified = $oldobj->new_id;
+                                }
 
-        // Calculate if we have perms to create users, by checking:
-        // to 'moodle/restore:createuser' and 'moodle/restore:userinfo'
-        // and also observe $CFG->disableusercreationonrestore
-        $cancreateuser = false;
-        if (has_capability('moodle/restore:createuser', $context) and
-            has_capability('moodle/restore:userinfo', $context) and
-            empty($CFG->disableusercreationonrestore)) { // Can create users
+                                if (backup_todb($info['GRADE_GRADES_HISTORY']['#']['RAWSCALEID']['0']['#'])) {
+                                    $scale = backup_getid($restore->backup_unique_code,"scale",backup_todb($info['GRADE_GRADES_HISTORY']['#']['RAWSCALEID']['0']['#']));
+                                    $dbrec->rawscaleid = $scale->new_id;
+                                }
 
-            $cancreateuser = true;
-        }
+                                $dbrec->finalgrade = backup_todb($info['GRADE_GRADES_HISTORY']['#']['FINALGRADE']['0']['#']);
+                                $dbrec->hidden = backup_todb($info['GRADE_GRADES_HISTORY']['#']['HIDDEN']['0']['#']);
+                                $dbrec->locked = backup_todb($info['GRADE_GRADES_HISTORY']['#']['LOCKED']['0']['#']);
+                                $dbrec->locktime = backup_todb($info['GRADE_GRADES_HISTORY']['#']['LOCKTIME']['0']['#']);
+                                $dbrec->exported = backup_todb($info['GRADE_GRADES_HISTORY']['#']['EXPORTED']['0']['#']);
+                                $dbrec->overridden = backup_todb($info['GRADE_GRADES_HISTORY']['#']['OVERRIDDEN']['0']['#']);
+                                $dbrec->excluded = backup_todb($info['GRADE_GRADES_HISTORY']['#']['EXCLUDED']['0']['#']);
+                                $dbrec->feedback = backup_todb($info['GRADE_TEXT_HISTORY']['#']['FEEDBACK']['0']['#']);
+                                $dbrec->feedbackformat = backup_todb($info['GRADE_TEXT_HISTORY']['#']['FEEDBACKFORMAT']['0']['#']);
+                                $dbrec->information = backup_todb($info['GRADE_TEXT_HISTORY']['#']['INFORMATION']['0']['#']);
+                                $dbrec->informationformat = backup_todb($info['GRADE_TEXT_HISTORY']['#']['INFORMATIONFORMAT']['0']['#']);
 
-        // Iterate over all users, checking if they are likely to cause problems on restore
-        $counter = 0;
-        foreach ($info->users as $userid) {
-            $rec = backup_getid($restore->backup_unique_code, 'user', $userid);
-            $user = $rec->info;
+                                $DB->insert_record('grade_grades_history', $dbrec);
+                                unset($dbrec);
 
-            // Find the correct mnethostid for user before performing any further check
-            if (empty($user->mnethosturl) || $user->mnethosturl === $CFG->wwwroot) {
-                $user->mnethostid = $CFG->mnet_localhost_id;
-            } else {
-                // fast url-to-id lookups
-                if (isset($mnethosts[$user->mnethosturl])) {
-                    $user->mnethostid = $mnethosts[$user->mnethosturl]->id;
-                } else {
-                    $user->mnethostid = $CFG->mnet_localhost_id;
+                            }
+                            //Increment counters
+                            $counter++;
+                            //Do some output
+                            if ($counter % 1 == 0) {
+                                if (!defined('RESTORE_SILENTLY')) {
+                                    echo ".";
+                                    if ($counter % 20 == 0) {
+                                        echo "<br />";
+                                    }
+                                }
+                                backup_flush(300);
+                            }
+                        }
+                    }
                 }
             }
 
-            // Calculate the best way to handle this user from backup file
-            $usercheck = restore_check_user($restore, $user);
-
-            if (is_object($usercheck)) { // No problem, we have found one user in DB to be mapped to
-                // Annotate it, for later process by restore_create_users(). Set new_id to mapping user->id
-                backup_putid($restore->backup_unique_code, 'user', $userid, $usercheck->id, $user);
-
-            } else if ($usercheck === false) { // Found conflict, report it as problem
-                $problems[] = get_string('restoreuserconflict', '', $user->username);
-                $status = false;
-
-            } else if ($usercheck === true) { // User needs to be created, check if we are able
-                if ($cancreateuser) { // Can create user, annotate it, for later process by restore_create_users(). Set new_id to 0
-                    backup_putid($restore->backup_unique_code, 'user', $userid, 0, $user);
-
-                } else { // Cannot create user, report it as problem
-
-                    $problems[] = get_string('restorecannotcreateuser', '', $user->username);
-                    $status = false;
-                }
+            // process histories
 
-            } else { // Shouldn't arrive here ever, something is for sure wrong in restore_check_user()
+            if ($gihcount && $status) {
                 if (!defined('RESTORE_SILENTLY')) {
-                    notify('Unexpected error pre-checking user ' . s($user->username) . ' from backup file');
-                    return false;
+                    echo '<li>'.get_string('gradeitemshistory','grades').'</li>';
                 }
-            }
+                $counter = 0;
+                while ($counter < $gihcount) {
+                    //Fetch recordset_size records in each iteration
+                    $recs = $DB->get_records("backup_ids", array('table_name'=>'grade_items_history', 'backup_code'=>$restore->backup_unique_code),
+                                                "old_id",
+                                                "old_id",
+                                                $counter,
+                                                $recordset_size);
+                    if ($recs) {
+                        foreach ($recs as $rec) {
+                            //Get the full record from backup_ids
+                            $data = backup_getid($restore->backup_unique_code,'grade_items_history',$rec->old_id);
+                            if ($data) {
+                                //Now get completed xmlized object
+                                $info = $data->info;
+                                //traverse_xmlize($info);                            //Debug
+                                //print_object ($GLOBALS['traverse_array']);         //Debug
+                                //$GLOBALS['traverse_array']="";                     //Debug
 
-            // Do some output
-            $counter++;
-            if ($counter % 10 == 0) {
-                if (!defined('RESTORE_SILENTLY')) {
-                    echo ".";
-                    if ($counter % 200 == 0) {
-                        echo "<br />";
-                    }
-                }
-                backup_flush(300);
-            }
-        }
 
-        return $status;
-    }
+                                $oldobj = backup_getid($restore->backup_unique_code,"grade_items", backup_todb($info['GRADE_ITEM_HISTORY']['#']['OLDID']['0']['#']));
+                                if (empty($oldobj->new_id)) {
+                                    // if the old object is not being restored, can't restoring its history
+                                    $counter++;
+                                    continue;
+                                }
+                                $dbrec->oldid = $oldobj->new_id;
+                                $dbrec->action = backup_todb($info['GRADE_ITEM_HISTORY']['#']['ACTION']['0']['#']);
+                                $dbrec->source = backup_todb($info['GRADE_ITEM_HISTORY']['#']['SOURCE']['0']['#']);
+                                $dbrec->timemodified = backup_todb($info['GRADE_ITEM_HISTORY']['#']['TIMEMODIFIED']['0']['#']);
+                                if ($oldobj = backup_getid($restore->backup_unique_code,"user", backup_todb($info['GRADE_ITEM_HISTORY']['#']['LOGGEDUSER']['0']['#']))) {
+                                    $dbrec->loggeduser = $oldobj->new_id;
+                                }
+                                $dbrec->courseid = $restore->course_id;
+                                $oldobj = backup_getid($restore->backup_unique_code,'grade_categories',backup_todb($info['GRADE_ITEM_HISTORY']['#']['CATEGORYID']['0']['#']));
+                                $oldobj->categoryid = $category->new_id;
+                                if (empty($oldobj->categoryid)) {
+                                    $counter++;
+                                    continue; // category not restored
+                                }
 
-    //This function create a new course record.
-    //When finished, course_header contains the id of the new course
-    function restore_create_new_course($restore,&$course_header) {
-        global $CFG, $DB;
+                                $dbrec->itemname= backup_todb($info['GRADE_ITEM_HISTORY']['#']['ITEMNAME']['0']['#']);
+                                $dbrec->itemtype = backup_todb($info['GRADE_ITEM_HISTORY']['#']['ITEMTYPE']['0']['#']);
+                                $dbrec->itemmodule = backup_todb($info['GRADE_ITEM_HISTORY']['#']['ITEMMODULE']['0']['#']);
 
+                                // code from grade_items restore
+                                $iteminstance = backup_todb($info['GRADE_ITEM_HISTORY']['#']['ITEMINSTANCE']['0']['#']);
+                                // do not restore if this grade_item is a mod, and
+                                if ($dbrec->itemtype == 'mod') {
 
-        //Create the course_object
-        if ($status) {
-            $course = new object();
-            $course->category = $course_header->category->id;
-            $course->password = $course_header->course_password;
-            $course->fullname = $course_header->course_fullname;
-            $course->shortname = $course_header->course_shortname;
-            $course->idnumber = $course_header->course_idnumber;
-            $course->idnumber = ''; //$course_header->course_idnumber; // we don't want this at all.
-            $course->summary = $course_header->course_summary;
-            $course->format = $course_header->course_format;
-            $course->showgrades = $course_header->course_showgrades;
-            $course->newsitems = $course_header->course_newsitems;
-            $course->guest = $course_header->course_guest;
-            $course->startdate = $course_header->course_startdate;
-            $course->startdate += $restore->course_startdateoffset;
-            $course->numsections = $course_header->course_numsections;
-            //$course->showrecent = $course_header->course_showrecent;   INFO: This is out in 1.3
-            $course->maxbytes = $course_header->course_maxbytes;
-            $course->showreports = $course_header->course_showreports;
-            if (isset($course_header->course_groupmode)) {
-                $course->groupmode = $course_header->course_groupmode;
-            }
-            if (isset($course_header->course_groupmodeforce)) {
-                $course->groupmodeforce = $course_header->course_groupmodeforce;
-            }
-            if (isset($course_header->course_defaultgroupingid)) {
-                //keep the original now - convert after groupings restored
-                $course->defaultgroupingid = $course_header->course_defaultgroupingid;
-            }
-            $course->lang = $course_header->course_lang;
-            $course->theme = $course_header->course_theme;
-            $course->cost = $course_header->course_cost;
-            $course->currency = isset($course_header->course_currency)?$course_header->course_currency:'';
-            $course->marker = $course_header->course_marker;
-            $course->visible = $course_header->course_visible;
-            $course->hiddensections = $course_header->course_hiddensections;
-            $course->timecreated = $course_header->course_timecreated;
-            $course->timemodified = $course_header->course_timemodified;
-            $course->metacourse = $course_header->course_metacourse;
-            $course->expirynotify = isset($course_header->course_expirynotify) ? $course_header->course_expirynotify:0;
-            $course->notifystudents = isset($course_header->course_notifystudents) ? $course_header->course_notifystudents : 0;
-            $course->expirythreshold = isset($course_header->course_expirythreshold) ? $course_header->course_expirythreshold : 0;
-            $course->enrollable = isset($course_header->course_enrollable) ? $course_header->course_enrollable : 1;
-            $course->enrolstartdate = isset($course_header->course_enrolstartdate) ? $course_header->course_enrolstartdate : 0;
-            if ($course->enrolstartdate)  { //Roll course dates
-                $course->enrolstartdate += $restore->course_startdateoffset;
-            }
-            $course->enrolenddate = isset($course_header->course_enrolenddate) ? $course_header->course_enrolenddate : 0;
-            if ($course->enrolenddate) { //Roll course dates
-                $course->enrolenddate  += $restore->course_startdateoffset;
-            }
-            $course->enrolperiod = $course_header->course_enrolperiod;
-            $course->enablecompletion = isset($course_header->course_enablecompletion) ? $course_header->course_enablecompletion : 0;
-            //Put as last course in category
-            $course->sortorder = $category->sortorder + MAX_COURSES_IN_CATEGORY - 1;
-
-            //Now, recode some languages (Moodle 1.5)
-            if ($course->lang == 'ma_nt') {
-                $course->lang = 'mi_nt';
-            }
+                                    if (!restore_userdata_selected($restore,  $dbrec->itemmodule, $iteminstance)) {
+                                        // module instance not selected when restored using granular
+                                        // skip this item
+                                        $counter++;
+                                        continue;
+                                    }
 
-            //Disable course->metacourse if avoided in restore config
-            if (!$restore->metacourse) {
-                $course->metacourse = 0;
-            }
+                                    // iteminstance should point to new mod
 
-            //Check if the theme exists in destination server
-            $themes = get_list_of_themes();
-            if (!in_array($course->theme, $themes)) {
-                $course->theme = '';
-            }
+                                    $mod = backup_getid($restore->backup_unique_code,$dbrec->itemmodule, $iteminstance);
+                                    $dbrec->iteminstance = $mod->new_id;
 
-            //Now insert the record
-            $newid = $DB->insert_record("course",$course);
-            if ($newid) {
-                //save old and new course id
-                backup_putid ($restore->backup_unique_code,"course",$course_header->course_id,$newid);
-                //Replace old course_id in course_header
-                $course_header->course_id = $newid;
-                $SESSION->restore->course_id = $newid;
-                return $newid;
-            } else {
-                $status = false;
-            }
-        }
+                                } else if ($dbrec->itemtype == 'category') {
+                                    // the item instance should point to the new grade category
 
-        return $status;
-    }
+                                    // only proceed if we are restoring all grade items
+                                    if ($restoreall) {
+                                        $category = backup_getid($restore->backup_unique_code,'grade_categories', $iteminstance);
+                                        $dbrec->iteminstance = $category->new_id;
+                                    } else {
+                                        // otherwise we can safely ignore this grade item and subsequent
+                                        // grade_raws, grade_finals etc
+                                        continue;
+                                    }
+                                } elseif ($dbrec->itemtype == 'course') { // We don't restore course type to avoid duplicate course items
+                                    if ($restoreall) {
+                                        // TODO any special code needed here to restore course item without duplicating it?
+                                        // find the course category with depth 1, and course id = current course id
+                                        // this would have been already restored
 
+                                        $cat = $DB->get_record('grade_categories', array('depth'=>1, 'courseid'=>$restore->course_id));
+                                        $dbrec->iteminstance = $cat->id;
 
-            // Now that we have IDs for everything, store any completion data
-            if($status && !empty($info->completiondata) && count($info->completiondata)>0) {
-                // Get list of users who can view course (& hence have
-                // completion data)
-                if(!isset($restore->userswhocanviewcourse)) {
-                    // Because this is only used here, there is no point requesting
-                    // anything except id
-                    $restore->userswhocanviewcourse = get_enrolled_users(get_context_instance(CONTEXT_COURSE, $restore->course_id), '', 0, 'u.id');
-                }
+                                    } else {
+                                        $counter++;
+                                        continue;
+                                    }
+                                }
 
-                foreach($info->completiondata as $data) {
-                    // Convert cmid
-                    $newcmid=backup_getid($restore->backup_unique_code, 'course_modules', $data->coursemoduleid);
-                    if($newcmid) {
-                        $data->coursemoduleid=$newcmid->new_id;
-                    } else {
-                        if (!defined('RESTORE_SILENTLY')) {
-                            echo "<p>Can't find new ID for cm $data->coursemoduleid.</p>";
-                        }
-                        $status=false;
-                        continue;
-                    }
+                                $dbrec->itemnumber = backup_todb($info['GRADE_ITEM_HISTORY']['#']['ITEMNUMBER']['0']['#']);
+                                $dbrec->iteminfo = backup_todb($info['GRADE_ITEM_HISTORY']['#']['ITEMINFO']['0']['#']);
+                                $dbrec->idnumber = backup_todb($info['GRADE_ITEM_HISTORY']['#']['IDNUMBER']['0']['#']);
+                                $dbrec->calculation = backup_todb($info['GRADE_ITEM_HISTORY']['#']['CALCULATION']['0']['#']);
+                                $dbrec->gradetype = backup_todb($info['GRADE_ITEM_HISTORY']['#']['GRADETYPE']['0']['#']);
+                                $dbrec->grademax = backup_todb($info['GRADE_ITEM_HISTORY']['#']['GRADEMAX']['0']['#']);
+                                $dbrec->grademin = backup_todb($info['GRADE_ITEM_HISTORY']['#']['GRADEMIN']['0']['#']);
+                                if ($oldobj = backup_getid($restore->backup_unique_code,"scale", backup_todb($info['GRADE_ITEM_HISTORY']['#']['SCALEID']['0']['#']))) {
+                                    // scaleid is optional
+                                    $dbrec->scaleid = $oldobj->new_id;
+                                }
+                                if ($oldobj = backup_getid($restore->backup_unique_code,"grade_outcomes", backup_todb($info['GRADE_ITEM_HISTORY']['#']['OUTCOMEID']['0']['#']))) {
+                                    // outcome is optional
+                                    $dbrec->outcomeid = $oldobj->new_id;
+                                }
+                                $dbrec->gradepass = backup_todb($info['GRADE_ITEM_HISTORY']['#']['GRADEPASS']['0']['#']);
+                                $dbrec->multfactor = backup_todb($info['GRADE_ITEM_HISTORY']['#']['MULTFACTOR']['0']['#']);
+                                $dbrec->plusfactor = backup_todb($info['GRADE_ITEM_HISTORY']['#']['PLUSFACTOR']['0']['#']);
+                                $dbrec->aggregationcoef = backup_todb($info['GRADE_ITEM_HISTORY']['#']['AGGREGATIONCOEF']['0']['#']);
+                                $dbrec->sortorder = backup_todb($info['GRADE_ITEM_HISTORY']['#']['SORTORDER']['0']['#']);
+                                $dbrec->display = backup_todb($info['GRADE_ITEM_HISTORY']['#']['DISPLAY']['0']['#']);
+                                $dbrec->decimals = backup_todb($info['GRADE_ITEM_HISTORY']['#']['DECIMALS']['0']['#']);
+                                $dbrec->hidden = backup_todb($info['GRADE_ITEM_HISTORY']['#']['HIDDEN']['0']['#']);
+                                $dbrec->locked = backup_todb($info['GRADE_ITEM_HISTORY']['#']['LOCKED']['0']['#']);
+                                $dbrec->locktime = backup_todb($info['GRADE_ITEM_HISTORY']['#']['LOCKTIME']['0']['#']);
+                                $dbrec->needsupdate = backup_todb($info['GRADE_ITEM_HISTORY']['#']['NEEDSUPDATE']['0']['#']);
 
-                    // Convert userid
-                    $newuserid=backup_getid($restore->backup_unique_code, 'user', $data->userid);
-                    if($newuserid) {
-                        $data->userid=$newuserid->new_id;
-                    } else {
-                        // Skip missing users
-                        debugging("Not restoring completion data for missing user {$data->userid}",DEBUG_DEVELOPER);
-                        continue;
-                    }
+                                $DB->insert_record('grade_items_history', $dbrec);
+                                unset($dbrec);
 
-                    // Check user is still able to access new course (they
-                    // might have had their role assignment excluded, and it
-                    // creates arguably bogus database rows if we add completion
-                    // data for them, and displays confusingly in the 'number
-                    // of people who have already marked this complete' UI)
-                    if(!array_key_exists($data->userid,$restore->userswhocanviewcourse)) {
-                        continue;
+                            }
+                            //Increment counters
+                            $counter++;
+                            //Do some output
+                            if ($counter % 1 == 0) {
+                                if (!defined('RESTORE_SILENTLY')) {
+                                    echo ".";
+                                    if ($counter % 20 == 0) {
+                                        echo "<br />";
+                                    }
+                                }
+                                backup_flush(300);
+                            }
+                        }
                     }
-
-                    // Add record
-                    $DB->insert_record('course_modules_completion',$data);
                 }
             }
 
-            // Store availability information
-            if($status && !empty($info->availabilitydata) && count($info->availabilitydata)>0) {
+            // process histories
+            if ($gohcount && $status) {
+                if (!defined('RESTORE_SILENTLY')) {
+                    echo '<li>'.get_string('gradeoutcomeshistory','grades').'</li>';
+                }
+                $counter = 0;
+                while ($counter < $gohcount) {
+                    //Fetch recordset_size records in each iteration
+                    $recs = $DB->get_records("backup_ids", array('table_name'=>'grade_outcomes_history', 'backup_code'=>$restore->backup_unique_code),
+                                                "old_id",
+                                                "old_id",
+                                                $counter,
+                                                $recordset_size);
+                    if ($recs) {
+                        foreach ($recs as $rec) {
+                            //Get the full record from backup_ids
+                            $data = backup_getid($restore->backup_unique_code,'grade_outcomes_history',$rec->old_id);
+                            if ($data) {
+                                //Now get completed xmlized object
+                                $info = $data->info;
+                                //traverse_xmlize($info);                            //Debug
+                                //print_object ($GLOBALS['traverse_array']);         //Debug
+                                //$GLOBALS['traverse_array']="";                     //Debug
 
-                foreach($info->availabilitydata as $data) {
-                    // Convert cmid
-                    $newcmid=backup_getid($restore->backup_unique_code, 'course_modules', $data->coursemoduleid);
-                    if($newcmid) {
-                        $data->coursemoduleid=$newcmid->new_id;
-                    } else {
-                        if (!defined('RESTORE_SILENTLY')) {
-                            echo "<p>Can't find new ID for cm $data->coursemoduleid, ignoring availability condition.</p>";
-                        }
-                        continue;
-                    }
+                                $oldobj = backup_getid($restore->backup_unique_code,"grade_outcomes", backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['OLDID']['0']['#']));
+                                if (empty($oldobj->new_id)) {
+                                    // if the old object is not being restored, can't restoring its history
+                                    $counter++;
+                                    continue;
+                                }
+                                $dbrec->oldid = $oldobj->new_id;
+                                $dbrec->action = backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['ACTION']['0']['#']);
+                                $dbrec->source = backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['SOURCE']['0']['#']);
+                                $dbrec->timemodified = backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['TIMEMODIFIED']['0']['#']);
+                                if ($oldobj = backup_getid($restore->backup_unique_code,"user", backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['LOGGEDUSER']['0']['#']))) {
+                                    $dbrec->loggeduser = $oldobj->new_id;
+                                }
+                                $dbrec->courseid = $restore->course_id;
+                                $dbrec->shortname = backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['SHORTNAME']['0']['#']);
+                                $dbrec->fullname= backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['FULLNAME']['0']['#']);
+                                $oldobj = backup_getid($restore->backup_unique_code,"scale", backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['SCALEID']['0']['#']));
+                                $dbrec->scaleid = $oldobj->new_id;
+                                $dbrec->description = backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['DESCRIPTION']['0']['#']);
+
+                                $DB->insert_record('grade_outcomes_history', $dbrec);
+                                unset($dbrec);
 
-                    // Convert source cmid
-                    if($data->sourcecmid) {
-                        $newcmid=backup_getid($restore->backup_unique_code, 'course_modules', $data->sourcecmid);
-                        if($newcmid) {
-                            $data->sourcecmid=$newcmid->new_id;
-                        } else {
-                            if (!defined('RESTORE_SILENTLY')) {
-                                echo "<p>Can't find new ID for source cm $data->sourcecmid, ignoring availability condition.</p>";
                             }
-                            continue;
+                            //Increment counters
+                            $counter++;
+                            //Do some output
+                            if ($counter % 1 == 0) {
+                                if (!defined('RESTORE_SILENTLY')) {
+                                    echo ".";
+                                    if ($counter % 20 == 0) {
+                                        echo "<br />";
+                                    }
+                                }
+                                backup_flush(300);
+                            }
                         }
                     }
-
-                    // Grade id is not converted (convert later)
-
-                    // Add record
-                    $DB->insert_record('course_modules_availability',$data);
                 }
             }
-        } else {
-            $status = false;
-        }
-        return $status;
-    }
-
-    //Called to set up any course-format specific data that may be in the file
-    function restore_set_format_data($restore,$xml_file) {
-        global $CFG, $DB;
-
-        $status = true;
-        //Check it exists
-        if (!file_exists($xml_file)) {
-            return false;
-        }
-        //Load data from XML to info
-        if(!($info = restore_read_xml_formatdata($xml_file))) {
-                return false;
         }
 
-        //Process format data if there is any
-        if (isset($info->format_data)) {
-                if(!$format=$DB->get_field('course','format', array('id'=>$restore->course_id))) {
-                    return false;
-                }
-                // If there was any data then it must have a restore method
-                $file=$CFG->dirroot."/course/format/$format/restorelib.php";
-                if(!file_exists($file)) {
-                    return false;
-                }
-                require_once($file);
-                $function=$format.'_restore_format_data';
-                if(!function_exists($function)) {
-                    return false;
-                }
-                return $function($restore,$info->format_data);
+        if (!defined('RESTORE_SILENTLY')) {
+        //End ul
+            echo '</ul>';
         }
-
-        // If we got here then there's no data, but that's cool
-        return true;
+        return $status;
     }
 
-
-    /**
-     * This function creates all the gradebook data from xml
-     */
-    function restore_create_gradebook($restore,$xml_file) {
+    //This function creates all the structures messages and contacts
+    function restore_create_messages($restore,$xml_file) {
         global $CFG, $DB;
 
         $status = true;
         //Check it exists
         if (!file_exists($xml_file)) {
-            return false;
-        }
-
-        // Get info from xml
-        // info will contain the number of record to process
-        $info = restore_read_xml_gradebook($restore, $xml_file);
-
-        // If we have info, then process
-        if (empty($info)) {
-            return $status;
-        }
-
-        if (empty($CFG->disablegradehistory) and isset($info->gradebook_histories) and $info->gradebook_histories == "true") {
-            $restore_histories = true;
-        } else {
-            $restore_histories = false;
+            $status = false;
         }
+        //Get info from xml
+        if ($status) {
+            //info will contain the id and name of every table
+            //(message, message_read and message_contacts)
+            //in backup_ids->info will be the real info (serialized)
+            $info = restore_read_xml_messages($restore,$xml_file);
 
-        // make sure top course category exists
-        $course_category = grade_category::fetch_course_category($restore->course_id);
-        $course_category->load_grade_item();
-
-        // we need to know if all grade items that were backed up are being restored
-        // if that is not the case, we do not restore grade categories nor gradeitems of category type or course type
-        // i.e. the aggregated grades of that category
-
-        $restoreall = true;  // set to false if any grade_item is not selected/restored or already exist
-        $importing  = !empty($SESSION->restore->importing);
-
-        if ($importing) {
-            $restoreall = false;
-
-        } else {
-            $prev_grade_items = grade_item::fetch_all(array('courseid'=>$restore->course_id));
-            $prev_grade_cats  = grade_category::fetch_all(array('courseid'=>$restore->course_id));
-
-             // if any categories already present, skip restore of categories from backup - course item or category already exist
-            if (count($prev_grade_items) > 1 or count($prev_grade_cats) > 1) {
-                $restoreall = false;
-            }
-            unset($prev_grade_items);
-            unset($prev_grade_cats);
-
-            if ($restoreall) {
-                if ($recs = $DB->get_records("backup_ids", array('table_name'=>'grade_items', 'backup_code'=>$restore->backup_unique_code), "", "old_id")) {
-                    foreach ($recs as $rec) {
-                        if ($data = backup_getid($restore->backup_unique_code,'grade_items',$rec->old_id)) {
-
-                            $info = $data->info;
-                            // do not restore if this grade_item is a mod, and
-                            $itemtype = backup_todb($info['GRADE_ITEM']['#']['ITEMTYPE']['0']['#']);
-
-                            if ($itemtype == 'mod') {
-                                $olditeminstance = backup_todb($info['GRADE_ITEM']['#']['ITEMINSTANCE']['0']['#']);
-                                $itemmodule      = backup_todb($info['GRADE_ITEM']['#']['ITEMMODULE']['0']['#']);
-
-                                if (empty($restore->mods[$itemmodule]->granular)) {
-                                    continue;
-                                } else if (!empty($restore->mods[$itemmodule]->instances[$olditeminstance]->restore)) {
-                                    continue;
-                                }
-                                // at least one activity should not be restored - do not restore categories and manual items at all
-                                $restoreall = false;
-                                break;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        // Start ul
-        if (!defined('RESTORE_SILENTLY')) {
-            echo '<ul>';
-        }
-
-        // array of restored categories - speedup ;-)
-        $cached_categories = array();
-        $outcomes          = array();
-
-    /// Process letters
-        $context = get_context_instance(CONTEXT_COURSE, $restore->course_id);
-        // respect current grade letters if defined
-        if ($status and $restoreall and !$DB->record_exists('grade_letters', array('contextid'=>$context->id))) {
-            if (!defined('RESTORE_SILENTLY')) {
-                echo '<li>'.get_string('gradeletters','grades').'</li>';
-            }
-            // Fetch recordset_size records in each iteration
-            $recs = $DB->get_records("backup_ids", array('table_name'=>'grade_letters', 'backup_code'=>$restore->backup_unique_code),
-                                        "",
-                                        "old_id");
-            if ($recs) {
-                foreach ($recs as $rec) {
-                    // Get the full record from backup_ids
-                    $data = backup_getid($restore->backup_unique_code,'grade_letters',$rec->old_id);
-                    if ($data) {
-                        $info = $data->info;
-                        $dbrec = new object();
-                        $dbrec->contextid     = $context->id;
-                        $dbrec->lowerboundary = backup_todb($info['GRADE_LETTER']['#']['LOWERBOUNDARY']['0']['#']);
-                        $dbrec->letter        = backup_todb($info['GRADE_LETTER']['#']['LETTER']['0']['#']);
-                        $DB->insert_record('grade_letters', $dbrec);
-                    }
-                }
-            }
-        }
-
-    /// Process grade items and grades
-        if ($status) {
-            if (!defined('RESTORE_SILENTLY')) {
-                echo '<li>'.get_string('gradeitems','grades').'</li>';
-            }
-            $counter = 0;
-
-            //Fetch recordset_size records in each iteration
-            $recs = $DB->get_records("backup_ids", array('table_name'=>'grade_items', 'backup_code'=>$restore->backup_unique_code),
-                                        "id", // restore in the backup order
-                                        "old_id");
-
-            if ($recs) {
-                foreach ($recs as $rec) {
-                    //Get the full record from backup_ids
-                    $data = backup_getid($restore->backup_unique_code,'grade_items',$rec->old_id);
-                    if ($data) {
-                        $info = $data->info;
-
-                        // first find out if category or normal item
-                        $itemtype =  backup_todb($info['GRADE_ITEM']['#']['ITEMTYPE']['0']['#'], false);
-                        if ($itemtype == 'course' or $itemtype == 'category') {
-                            if (!$restoreall or $importing) {
-                                continue;
-                            }
-
-                            $oldcat = backup_todb($info['GRADE_ITEM']['#']['ITEMINSTANCE']['0']['#'], false);
-                            if (!$cdata = backup_getid($restore->backup_unique_code,'grade_categories',$oldcat)) {
-                                continue;
-                            }
-                            $cinfo = $cdata->info;
-                            unset($cdata);
-                            if ($itemtype == 'course') {
-
-                                $course_category->fullname            = backup_todb($cinfo['GRADE_CATEGORY']['#']['FULLNAME']['0']['#'], false);
-                                $course_category->aggregation         = backup_todb($cinfo['GRADE_CATEGORY']['#']['AGGREGATION']['0']['#'], false);
-                                $course_category->keephigh            = backup_todb($cinfo['GRADE_CATEGORY']['#']['KEEPHIGH']['0']['#'], false);
-                                $course_category->droplow             = backup_todb($cinfo['GRADE_CATEGORY']['#']['DROPLOW']['0']['#'], false);
-                                $course_category->aggregateonlygraded = backup_todb($cinfo['GRADE_CATEGORY']['#']['AGGREGATEONLYGRADED']['0']['#'], false);
-                                $course_category->aggregateoutcomes   = backup_todb($cinfo['GRADE_CATEGORY']['#']['AGGREGATEOUTCOMES']['0']['#'], false);
-                                $course_category->aggregatesubcats    = backup_todb($cinfo['GRADE_CATEGORY']['#']['AGGREGATESUBCATS']['0']['#'], false);
-                                $course_category->timecreated         = backup_todb($cinfo['GRADE_CATEGORY']['#']['TIMECREATED']['0']['#'], false);
-                                $course_category->update('restore');
-
-                                $status = backup_putid($restore->backup_unique_code,'grade_categories',$oldcat,$course_category->id) && $status;
-                                $cached_categories[$oldcat] = $course_category;
-                                $grade_item = $course_category->get_grade_item();
-
-                            } else {
-                                $oldparent = backup_todb($cinfo['GRADE_CATEGORY']['#']['PARENT']['0']['#'], false);
-                                if (empty($cached_categories[$oldparent])) {
-                                    debugging('parent not found '.$oldparent);
-                                    continue; // parent not found, sorry
-                                }
-                                $grade_category = new grade_category();
-                                $grade_category->courseid            = $restore->course_id;
-                                $grade_category->parent              = $cached_categories[$oldparent]->id;
-                                $grade_category->fullname            = backup_todb($cinfo['GRADE_CATEGORY']['#']['FULLNAME']['0']['#'], false);
-                                $grade_category->aggregation         = backup_todb($cinfo['GRADE_CATEGORY']['#']['AGGREGATION']['0']['#'], false);
-                                $grade_category->keephigh            = backup_todb($cinfo['GRADE_CATEGORY']['#']['KEEPHIGH']['0']['#'], false);
-                                $grade_category->droplow             = backup_todb($cinfo['GRADE_CATEGORY']['#']['DROPLOW']['0']['#'], false);
-                                $grade_category->aggregateonlygraded = backup_todb($cinfo['GRADE_CATEGORY']['#']['AGGREGATEONLYGRADED']['0']['#'], false);
-                                $grade_category->aggregateoutcomes   = backup_todb($cinfo['GRADE_CATEGORY']['#']['AGGREGATEOUTCOMES']['0']['#'], false);
-                                $grade_category->aggregatesubcats    = backup_todb($cinfo['GRADE_CATEGORY']['#']['AGGREGATESUBCATS']['0']['#'], false);
-                                $grade_category->timecreated         = backup_todb($cinfo['GRADE_CATEGORY']['#']['TIMECREATED']['0']['#'], false);
-                                $grade_category->insert('restore');
-
-                                $status = backup_putid($restore->backup_unique_code,'grade_categories',$oldcat,$grade_category->id) && $status;
-                                $cached_categories[$oldcat] = $grade_category;
-                                $grade_item = $grade_category->get_grade_item(); // creates grade_item too
-                            }
-                            unset($cinfo);
-
-                            $idnumber = backup_todb($info['GRADE_ITEM']['#']['IDNUMBER']['0']['#'], false);
-                            if (grade_verify_idnumber($idnumber, $restore->course_id)) {
-                                $grade_item->idnumber    = $idnumber;
-                            }
-
-                            $grade_item->itemname        = backup_todb($info['GRADE_ITEM']['#']['ITEMNAME']['0']['#'], false);
-                            $grade_item->iteminfo        = backup_todb($info['GRADE_ITEM']['#']['ITEMINFO']['0']['#'], false);
-                            $grade_item->gradetype       = backup_todb($info['GRADE_ITEM']['#']['GRADETYPE']['0']['#'], false);
-                            $grade_item->calculation     = backup_todb($info['GRADE_ITEM']['#']['CALCULATION']['0']['#'], false);
-                            $grade_item->grademax        = backup_todb($info['GRADE_ITEM']['#']['GRADEMAX']['0']['#'], false);
-                            $grade_item->grademin        = backup_todb($info['GRADE_ITEM']['#']['GRADEMIN']['0']['#'], false);
-                            $grade_item->gradepass       = backup_todb($info['GRADE_ITEM']['#']['GRADEPASS']['0']['#'], false);
-                            $grade_item->multfactor      = backup_todb($info['GRADE_ITEM']['#']['MULTFACTOR']['0']['#'], false);
-                            $grade_item->plusfactor      = backup_todb($info['GRADE_ITEM']['#']['PLUSFACTOR']['0']['#'], false);
-                            $grade_item->aggregationcoef = backup_todb($info['GRADE_ITEM']['#']['AGGREGATIONCOEF']['0']['#'], false);
-                            $grade_item->display         = backup_todb($info['GRADE_ITEM']['#']['DISPLAY']['0']['#'], false);
-                            $grade_item->decimals        = backup_todb($info['GRADE_ITEM']['#']['DECIMALS']['0']['#'], false);
-                            $grade_item->hidden          = backup_todb($info['GRADE_ITEM']['#']['HIDDEN']['0']['#'], false);
-                            $grade_item->locked          = backup_todb($info['GRADE_ITEM']['#']['LOCKED']['0']['#'], false);
-                            $grade_item->locktime        = backup_todb($info['GRADE_ITEM']['#']['LOCKTIME']['0']['#'], false);
-                            $grade_item->timecreated     = backup_todb($info['GRADE_ITEM']['#']['TIMECREATED']['0']['#'], false);
-
-                            if (backup_todb($info['GRADE_ITEM']['#']['SCALEID']['0']['#'], false)) {
-                                $scale = backup_getid($restore->backup_unique_code,"scale",backup_todb($info['GRADE_ITEM']['#']['SCALEID']['0']['#'], false));
-                                $grade_item->scaleid     = $scale->new_id;
-                            }
-
-                            if  (backup_todb($info['GRADE_ITEM']['#']['OUTCOMEID']['0']['#'], false)) {
-                                $outcome = backup_getid($restore->backup_unique_code,"grade_outcomes",backup_todb($info['GRADE_ITEM']['#']['OUTCOMEID']['0']['#'], false));
-                                $grade_item->outcomeid   = $outcome->new_id;
-                            }
-
-                            $grade_item->update('restore');
-                            $status = backup_putid($restore->backup_unique_code,"grade_items", $rec->old_id, $grade_item->id) && $status;
-
-                        } else {
-                            if ($itemtype != 'mod' and (!$restoreall or $importing)) {
-                                // not extra gradebook stuff if restoring individual activities or something already there
-                                continue;
-                            }
-
-                            $dbrec = new object();
-
-                            $dbrec->courseid      = $restore->course_id;
-                            $dbrec->itemtype      = backup_todb($info['GRADE_ITEM']['#']['ITEMTYPE']['0']['#'], false);
-                            $dbrec->itemmodule    = backup_todb($info['GRADE_ITEM']['#']['ITEMMODULE']['0']['#'], false);
-
-                            if ($itemtype == 'mod') {
-                                // iteminstance should point to new mod
-                                $olditeminstance = backup_todb($info['GRADE_ITEM']['#']['ITEMINSTANCE']['0']['#'], false);
-                                $mod = backup_getid($restore->backup_unique_code,$dbrec->itemmodule, $olditeminstance);
-                                $dbrec->iteminstance = $mod->new_id;
-                                if (!$cm = get_coursemodule_from_instance($dbrec->itemmodule, $mod->new_id)) {
-                                    // item not restored - no item
-                                    continue;
-                                }
-                                // keep in sync with activity idnumber
-                                $dbrec->idnumber = $cm->idnumber;
-
-                            } else {
-                                $idnumber = backup_todb($info['GRADE_ITEM']['#']['IDNUMBER']['0']['#'], false);
-
-                                if (grade_verify_idnumber($idnumber, $restore->course_id)) {
-                                    //make sure the new idnumber is unique
-                                    $dbrec->idnumber  = $idnumber;
-                                }
-                            }
-
-                            $dbrec->itemname        = backup_todb($info['GRADE_ITEM']['#']['ITEMNAME']['0']['#'], false);
-                            $dbrec->itemtype        = backup_todb($info['GRADE_ITEM']['#']['ITEMTYPE']['0']['#'], false);
-                            $dbrec->itemmodule      = backup_todb($info['GRADE_ITEM']['#']['ITEMMODULE']['0']['#'], false);
-                            $dbrec->itemnumber      = backup_todb($info['GRADE_ITEM']['#']['ITEMNUMBER']['0']['#'], false);
-                            $dbrec->iteminfo        = backup_todb($info['GRADE_ITEM']['#']['ITEMINFO']['0']['#'], false);
-                            $dbrec->gradetype       = backup_todb($info['GRADE_ITEM']['#']['GRADETYPE']['0']['#'], false);
-                            $dbrec->calculation     = backup_todb($info['GRADE_ITEM']['#']['CALCULATION']['0']['#'], false);
-                            $dbrec->grademax        = backup_todb($info['GRADE_ITEM']['#']['GRADEMAX']['0']['#'], false);
-                            $dbrec->grademin        = backup_todb($info['GRADE_ITEM']['#']['GRADEMIN']['0']['#'], false);
-                            $dbrec->gradepass       = backup_todb($info['GRADE_ITEM']['#']['GRADEPASS']['0']['#'], false);
-                            $dbrec->multfactor      = backup_todb($info['GRADE_ITEM']['#']['MULTFACTOR']['0']['#'], false);
-                            $dbrec->plusfactor      = backup_todb($info['GRADE_ITEM']['#']['PLUSFACTOR']['0']['#'], false);
-                            $dbrec->aggregationcoef = backup_todb($info['GRADE_ITEM']['#']['AGGREGATIONCOEF']['0']['#'], false);
-                            $dbrec->display         = backup_todb($info['GRADE_ITEM']['#']['DISPLAY']['0']['#'], false);
-                            $dbrec->decimals        = backup_todb($info['GRADE_ITEM']['#']['DECIMALS']['0']['#'], false);
-                            $dbrec->hidden          = backup_todb($info['GRADE_ITEM']['#']['HIDDEN']['0']['#'], false);
-                            $dbrec->locked          = backup_todb($info['GRADE_ITEM']['#']['LOCKED']['0']['#'], false);
-                            $dbrec->locktime        = backup_todb($info['GRADE_ITEM']['#']['LOCKTIME']['0']['#'], false);
-                            $dbrec->timecreated     = backup_todb($info['GRADE_ITEM']['#']['TIMECREATED']['0']['#'], false);
-
-                            if (backup_todb($info['GRADE_ITEM']['#']['SCALEID']['0']['#'], false)) {
-                                $scale = backup_getid($restore->backup_unique_code,"scale",backup_todb($info['GRADE_ITEM']['#']['SCALEID']['0']['#'], false));
-                                $dbrec->scaleid = $scale->new_id;
-                            }
-
-                            if  (backup_todb($info['GRADE_ITEM']['#']['OUTCOMEID']['0']['#'])) {
-                                $oldoutcome = backup_todb($info['GRADE_ITEM']['#']['OUTCOMEID']['0']['#']);
-                                if (empty($outcomes[$oldoutcome])) {
-                                    continue; // error!
-                                }
-                                if (empty($outcomes[$oldoutcome]->id)) {
-                                    $outcomes[$oldoutcome]->insert('restore');
-                                    $outcomes[$oldoutcome]->use_in($restore->course_id);
-                                    backup_putid($restore->backup_unique_code, "grade_outcomes", $oldoutcome, $outcomes[$oldoutcome]->id);
-                                }
-                                $dbrec->outcomeid = $outcomes[$oldoutcome]->id;
-                            }
-
-                            $grade_item = new grade_item($dbrec, false);
-                            $grade_item->insert('restore');
-                            if ($restoreall) {
-                                // set original parent if restored
-                                $oldcat = $info['GRADE_ITEM']['#']['CATEGORYID']['0']['#'];
-                                if (!empty($cached_categories[$oldcat])) {
-                                    $grade_item->set_parent($cached_categories[$oldcat]->id);
-                                }
-                            }
-                            $status = backup_putid($restore->backup_unique_code,"grade_items", $rec->old_id, $grade_item->id) && $status;
-                        }
-
-                        // no need to restore grades if user data is not selected or importing activities
-                        if ($importing
-                          or ($grade_item->itemtype == 'mod' and !restore_userdata_selected($restore,  $grade_item->itemmodule, $olditeminstance))) {
-                            // module instance not selected when restored using granular
-                            // skip this item
-                            continue;
-                        }
-
-                        /// now, restore grade_grades
-                        if (!empty($info['GRADE_ITEM']['#']['GRADE_GRADES']['0']['#']['GRADE'])) {
-                            //Iterate over items
-                            foreach ($info['GRADE_ITEM']['#']['GRADE_GRADES']['0']['#']['GRADE'] as $g_info) {
-
-                                $grade = new grade_grade();
-                                $grade->itemid         = $grade_item->id;
-
-                                $olduser = backup_todb($g_info['#']['USERID']['0']['#'], false);
-                                $user = backup_getid($restore->backup_unique_code,"user",$olduser);
-                                $grade->userid         = $user->new_id;
-
-                                $grade->rawgrade       = backup_todb($g_info['#']['RAWGRADE']['0']['#'], false);
-                                $grade->rawgrademax    = backup_todb($g_info['#']['RAWGRADEMAX']['0']['#'], false);
-                                $grade->rawgrademin    = backup_todb($g_info['#']['RAWGRADEMIN']['0']['#'], false);
-                                // need to find scaleid
-                                if (backup_todb($g_info['#']['RAWSCALEID']['0']['#'])) {
-                                    $scale = backup_getid($restore->backup_unique_code,"scale",backup_todb($g_info['#']['RAWSCALEID']['0']['#'], false));
-                                    $grade->rawscaleid = $scale->new_id;
-                                }
-
-                                if (backup_todb($g_info['#']['USERMODIFIED']['0']['#'])) {
-                                    if ($modifier = backup_getid($restore->backup_unique_code,"user", backup_todb($g_info['#']['USERMODIFIED']['0']['#'], false))) {
-                                        $grade->usermodified = $modifier->new_id;
-                                    }
-                                }
-
-                                $grade->finalgrade        = backup_todb($g_info['#']['FINALGRADE']['0']['#'], false);
-                                $grade->hidden            = backup_todb($g_info['#']['HIDDEN']['0']['#'], false);
-                                $grade->locked            = backup_todb($g_info['#']['LOCKED']['0']['#'], false);
-                                $grade->locktime          = backup_todb($g_info['#']['LOCKTIME']['0']['#'], false);
-                                $grade->exported          = backup_todb($g_info['#']['EXPORTED']['0']['#'], false);
-                                $grade->overridden        = backup_todb($g_info['#']['OVERRIDDEN']['0']['#'], false);
-                                $grade->excluded          = backup_todb($g_info['#']['EXCLUDED']['0']['#'], false);
-                                $grade->feedback          = backup_todb($g_info['#']['FEEDBACK']['0']['#'], false);
-                                $grade->feedbackformat    = backup_todb($g_info['#']['FEEDBACKFORMAT']['0']['#'], false);
-                                $grade->information       = backup_todb($g_info['#']['INFORMATION']['0']['#'], false);
-                                $grade->informationformat = backup_todb($g_info['#']['INFORMATIONFORMAT']['0']['#'], false);
-                                $grade->timecreated       = backup_todb($g_info['#']['TIMECREATED']['0']['#'], false);
-                                $grade->timemodified      = backup_todb($g_info['#']['TIMEMODIFIED']['0']['#'], false);
-
-                                $grade->insert('restore');
-                                backup_putid($restore->backup_unique_code,"grade_grades", backup_todb($g_info['#']['ID']['0']['#']), $grade->id);
-
-                                $counter++;
-                                if ($counter % 20 == 0) {
-                                    if (!defined('RESTORE_SILENTLY')) {
-                                        echo ".";
-                                        if ($counter % 400 == 0) {
-                                            echo "<br />";
-                                        }
-                                    }
-                                    backup_flush(300);
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-    /// add outcomes that are not used when doing full restore
-        if ($status and $restoreall) {
-            foreach ($outcomes as $oldoutcome=>$grade_outcome) {
-                if (empty($grade_outcome->id)) {
-                    $grade_outcome->insert('restore');
-                    $grade_outcome->use_in($restore->course_id);
-                    backup_putid($restore->backup_unique_code, "grade_outcomes", $oldoutcome, $grade_outcome->id);
-                }
-            }
-        }
-
-
-        if ($status and !$importing and $restore_histories) {
-            /// following code is very inefficient
-
-            $gchcount = $DB->count_records('backup_ids', array('backup_code'=>$restore->backup_unique_code, 'table_name'=>'grade_categories_history'));
-            $gghcount = $DB->count_records('backup_ids', array('backup_code'=>$restore->backup_unique_code, 'table_name'=>'grade_grades_history'));
-            $gihcount = $DB->count_records('backup_ids', array('backup_code'=>$restore->backup_unique_code, 'table_name'=>'grade_items_history'));
-            $gohcount = $DB->count_records('backup_ids', array('backup_code'=>$restore->backup_unique_code, 'table_name'=>'grade_outcomes_history'));
-
-            // Number of records to get in every chunk
-            $recordset_size = 2;
-
-            // process histories
-            if ($gchcount && $status) {
-                if (!defined('RESTORE_SILENTLY')) {
-                    echo '<li>'.get_string('gradecategoryhistory','grades').'</li>';
-                }
-                $counter = 0;
-                while ($counter < $gchcount) {
-                    //Fetch recordset_size records in each iteration
-                    $recs = $DB->get_records("backup_ids",array('table_name'=>'grade_categories_history', 'backup_code'=>$restore->backup_unique_code),
-                                                "old_id",
-                                                "old_id",
-                                                $counter,
-                                                $recordset_size);
-                    if ($recs) {
-                        foreach ($recs as $rec) {
-                            //Get the full record from backup_ids
-                            $data = backup_getid($restore->backup_unique_code,'grade_categories_history',$rec->old_id);
-                            if ($data) {
-                                //Now get completed xmlized object
-                                $info = $data->info;
-                                //traverse_xmlize($info);                            //Debug
-                                //print_object ($GLOBALS['traverse_array']);         //Debug
-                                //$GLOBALS['traverse_array']="";                     //Debug
-
-                                $oldobj = backup_getid($restore->backup_unique_code,"grade_categories", backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['OLDID']['0']['#']));
-                                if (empty($oldobj->new_id)) {
-                                    // if the old object is not being restored, can't restoring its history
-                                    $counter++;
-                                    continue;
-                                }
-                                $dbrec->oldid = $oldobj->new_id;
-                                $dbrec->action = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['ACTION']['0']['#']);
-                                $dbrec->source = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['SOURCE']['0']['#']);
-                                $dbrec->timemodified = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['TIMEMODIFIED']['0']['#']);
-
-                                // loggeduser might not be restored, e.g. admin
-                                if ($oldobj = backup_getid($restore->backup_unique_code,"user", backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['LOGGEDUSER']['0']['#']))) {
-                                    $dbrec->loggeduser = $oldobj->new_id;
-                                }
-
-                                // this item might not have a parent at all, do not skip it if no parent is specified
-                                if (backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['PARENT']['0']['#'])) {
-                                    $oldobj = backup_getid($restore->backup_unique_code,"grade_categories", backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['PARENT']['0']['#']));
-                                    if (empty($oldobj->new_id)) {
-                                        // if the parent category not restored
-                                        $counter++;
-                                        continue;
-                                    }
-                                }
-                                $dbrec->parent = $oldobj->new_id;
-                                $dbrec->depth = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['DEPTH']['0']['#']);
-                                // path needs to be rebuilt
-                                if ($path = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['PATH']['0']['#'])) {
-                                // to preserve the path and make it work, we need to replace the categories one by one
-                                // we first get the list of categories in current path
-                                    if ($paths = explode("/", $path)) {
-                                        $newpath = '';
-                                        foreach ($paths as $catid) {
-                                            if ($catid) {
-                                                // find the new corresponding path
-                                                $oldpath = backup_getid($restore->backup_unique_code,"grade_categories", $catid);
-                                                $newpath .= "/$oldpath->new_id";
-                                            }
-                                        }
-                                        $dbrec->path = $newpath;
-                                    }
-                                }
-                                $dbrec->fullname = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['FULLNAME']['0']['#']);
-                                $dbrec->aggregation = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['AGGRETGATION']['0']['#']);
-                                $dbrec->keephigh = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['KEEPHIGH']['0']['#']);
-                                $dbrec->droplow = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['DROPLOW']['0']['#']);
-
-                                $dbrec->aggregateonlygraded = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['AGGREGATEONLYGRADED']['0']['#']);
-                                $dbrec->aggregateoutcomes = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['AGGREGATEOUTCOMES']['0']['#']);
-                                $dbrec->aggregatesubcats = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['AGGREGATESUBCATS']['0']['#']);
-
-                                $dbrec->courseid = $restore->course_id;
-                                $DB->insert_record('grade_categories_history', $dbrec);
-                                unset($dbrec);
-
-                            }
-                            //Increment counters
-                            $counter++;
-                            //Do some output
-                            if ($counter % 1 == 0) {
-                                if (!defined('RESTORE_SILENTLY')) {
-                                    echo ".";
-                                    if ($counter % 20 == 0) {
-                                        echo "<br />";
-                                    }
-                                }
-                                backup_flush(300);
-                            }
-                        }
-                    }
-                }
-            }
-
-            // process histories
-            if ($gghcount && $status) {
-                if (!defined('RESTORE_SILENTLY')) {
-                    echo '<li>'.get_string('gradegradeshistory','grades').'</li>';
-                }
-                $counter = 0;
-                while ($counter < $gghcount) {
-                    //Fetch recordset_size records in each iteration
-                    $recs = $DB->get_records("backup_ids", array('table_name'=>'grade_grades_history', 'backup_code'=>$restore->backup_unique_code),
-                                                "old_id",
-                                                "old_id",
-                                                $counter,
-                                                $recordset_size);
-                    if ($recs) {
-                        foreach ($recs as $rec) {
-                            //Get the full record from backup_ids
-                            $data = backup_getid($restore->backup_unique_code,'grade_grades_history',$rec->old_id);
-                            if ($data) {
-                                //Now get completed xmlized object
-                                $info = $data->info;
-                                //traverse_xmlize($info);                            //Debug
-                                //print_object ($GLOBALS['traverse_array']);         //Debug
-                                //$GLOBALS['traverse_array']="";                     //Debug
-
-                                $oldobj = backup_getid($restore->backup_unique_code,"grade_grades", backup_todb($info['GRADE_GRADES_HISTORY']['#']['OLDID']['0']['#']));
-                                if (empty($oldobj->new_id)) {
-                                    // if the old object is not being restored, can't restoring its history
-                                    $counter++;
-                                    continue;
-                                }
-                                $dbrec->oldid = $oldobj->new_id;
-                                $dbrec->action = backup_todb($info['GRADE_GRADES_HISTORY']['#']['ACTION']['0']['#']);
-                                $dbrec->source = backup_todb($info['GRADE_GRADES_HISTORY']['#']['SOURCE']['0']['#']);
-                                $dbrec->timemodified = backup_todb($info['GRADE_GRADES_HISTORY']['#']['TIMEMODIFIED']['0']['#']);
-                                if ($oldobj = backup_getid($restore->backup_unique_code,"user", backup_todb($info['GRADE_GRADES_HISTORY']['#']['LOGGEDUSER']['0']['#']))) {
-                                    $dbrec->loggeduser = $oldobj->new_id;
-                                }
-
-                                $oldobj = backup_getid($restore->backup_unique_code,"grade_items", backup_todb($info['GRADE_GRADES_HISTORY']['#']['ITEMID']['0']['#']));
-                                $dbrec->itemid = $oldobj->new_id;
-                                if (empty($dbrec->itemid)) {
-                                    $counter++;
-                                    continue; // grade item not being restored
-                                }
-                                $oldobj = backup_getid($restore->backup_unique_code,"user", backup_todb($info['GRADE_GRADES_HISTORY']['#']['USERID']['0']['#']));
-                                $dbrec->userid = $oldobj->new_id;
-                                $dbrec->rawgrade = backup_todb($info['GRADE_GRADES_HISTORY']['#']['RAWGRADE']['0']['#']);
-                                $dbrec->rawgrademax = backup_todb($info['GRADE_GRADES_HISTORY']['#']['RAWGRADEMAX']['0']['#']);
-                                $dbrec->rawgrademin = backup_todb($info['GRADE_GRADES_HISTORY']['#']['RAWGRADEMIN']['0']['#']);
-                                if ($oldobj = backup_getid($restore->backup_unique_code,"user", backup_todb($info['GRADE_GRADES_HISTORY']['#']['USERMODIFIED']['0']['#']))) {
-                                    $dbrec->usermodified = $oldobj->new_id;
-                                }
-
-                                if (backup_todb($info['GRADE_GRADES_HISTORY']['#']['RAWSCALEID']['0']['#'])) {
-                                    $scale = backup_getid($restore->backup_unique_code,"scale",backup_todb($info['GRADE_GRADES_HISTORY']['#']['RAWSCALEID']['0']['#']));
-                                    $dbrec->rawscaleid = $scale->new_id;
-                                }
-
-                                $dbrec->finalgrade = backup_todb($info['GRADE_GRADES_HISTORY']['#']['FINALGRADE']['0']['#']);
-                                $dbrec->hidden = backup_todb($info['GRADE_GRADES_HISTORY']['#']['HIDDEN']['0']['#']);
-                                $dbrec->locked = backup_todb($info['GRADE_GRADES_HISTORY']['#']['LOCKED']['0']['#']);
-                                $dbrec->locktime = backup_todb($info['GRADE_GRADES_HISTORY']['#']['LOCKTIME']['0']['#']);
-                                $dbrec->exported = backup_todb($info['GRADE_GRADES_HISTORY']['#']['EXPORTED']['0']['#']);
-                                $dbrec->overridden = backup_todb($info['GRADE_GRADES_HISTORY']['#']['OVERRIDDEN']['0']['#']);
-                                $dbrec->excluded = backup_todb($info['GRADE_GRADES_HISTORY']['#']['EXCLUDED']['0']['#']);
-                                $dbrec->feedback = backup_todb($info['GRADE_TEXT_HISTORY']['#']['FEEDBACK']['0']['#']);
-                                $dbrec->feedbackformat = backup_todb($info['GRADE_TEXT_HISTORY']['#']['FEEDBACKFORMAT']['0']['#']);
-                                $dbrec->information = backup_todb($info['GRADE_TEXT_HISTORY']['#']['INFORMATION']['0']['#']);
-                                $dbrec->informationformat = backup_todb($info['GRADE_TEXT_HISTORY']['#']['INFORMATIONFORMAT']['0']['#']);
-
-                                $DB->insert_record('grade_grades_history', $dbrec);
-                                unset($dbrec);
-
-                            }
-                            //Increment counters
-                            $counter++;
-                            //Do some output
-                            if ($counter % 1 == 0) {
-                                if (!defined('RESTORE_SILENTLY')) {
-                                    echo ".";
-                                    if ($counter % 20 == 0) {
-                                        echo "<br />";
-                                    }
-                                }
-                                backup_flush(300);
-                            }
-                        }
-                    }
-                }
-            }
-
-            // process histories
-
-            if ($gihcount && $status) {
-                if (!defined('RESTORE_SILENTLY')) {
-                    echo '<li>'.get_string('gradeitemshistory','grades').'</li>';
-                }
-                $counter = 0;
-                while ($counter < $gihcount) {
-                    //Fetch recordset_size records in each iteration
-                    $recs = $DB->get_records("backup_ids", array('table_name'=>'grade_items_history', 'backup_code'=>$restore->backup_unique_code),
-                                                "old_id",
-                                                "old_id",
-                                                $counter,
-                                                $recordset_size);
-                    if ($recs) {
-                        foreach ($recs as $rec) {
-                            //Get the full record from backup_ids
-                            $data = backup_getid($restore->backup_unique_code,'grade_items_history',$rec->old_id);
-                            if ($data) {
-                                //Now get completed xmlized object
-                                $info = $data->info;
-                                //traverse_xmlize($info);                            //Debug
-                                //print_object ($GLOBALS['traverse_array']);         //Debug
-                                //$GLOBALS['traverse_array']="";                     //Debug
-
-
-                                $oldobj = backup_getid($restore->backup_unique_code,"grade_items", backup_todb($info['GRADE_ITEM_HISTORY']['#']['OLDID']['0']['#']));
-                                if (empty($oldobj->new_id)) {
-                                    // if the old object is not being restored, can't restoring its history
-                                    $counter++;
-                                    continue;
-                                }
-                                $dbrec->oldid = $oldobj->new_id;
-                                $dbrec->action = backup_todb($info['GRADE_ITEM_HISTORY']['#']['ACTION']['0']['#']);
-                                $dbrec->source = backup_todb($info['GRADE_ITEM_HISTORY']['#']['SOURCE']['0']['#']);
-                                $dbrec->timemodified = backup_todb($info['GRADE_ITEM_HISTORY']['#']['TIMEMODIFIED']['0']['#']);
-                                if ($oldobj = backup_getid($restore->backup_unique_code,"user", backup_todb($info['GRADE_ITEM_HISTORY']['#']['LOGGEDUSER']['0']['#']))) {
-                                    $dbrec->loggeduser = $oldobj->new_id;
-                                }
-                                $dbrec->courseid = $restore->course_id;
-                                $oldobj = backup_getid($restore->backup_unique_code,'grade_categories',backup_todb($info['GRADE_ITEM_HISTORY']['#']['CATEGORYID']['0']['#']));
-                                $oldobj->categoryid = $category->new_id;
-                                if (empty($oldobj->categoryid)) {
-                                    $counter++;
-                                    continue; // category not restored
-                                }
-
-                                $dbrec->itemname= backup_todb($info['GRADE_ITEM_HISTORY']['#']['ITEMNAME']['0']['#']);
-                                $dbrec->itemtype = backup_todb($info['GRADE_ITEM_HISTORY']['#']['ITEMTYPE']['0']['#']);
-                                $dbrec->itemmodule = backup_todb($info['GRADE_ITEM_HISTORY']['#']['ITEMMODULE']['0']['#']);
-
-                                // code from grade_items restore
-                                $iteminstance = backup_todb($info['GRADE_ITEM_HISTORY']['#']['ITEMINSTANCE']['0']['#']);
-                                // do not restore if this grade_item is a mod, and
-                                if ($dbrec->itemtype == 'mod') {
-
-                                    if (!restore_userdata_selected($restore,  $dbrec->itemmodule, $iteminstance)) {
-                                        // module instance not selected when restored using granular
-                                        // skip this item
-                                        $counter++;
-                                        continue;
-                                    }
-
-                                    // iteminstance should point to new mod
-
-                                    $mod = backup_getid($restore->backup_unique_code,$dbrec->itemmodule, $iteminstance);
-                                    $dbrec->iteminstance = $mod->new_id;
-
-                                } else if ($dbrec->itemtype == 'category') {
-                                    // the item instance should point to the new grade category
-
-                                    // only proceed if we are restoring all grade items
-                                    if ($restoreall) {
-                                        $category = backup_getid($restore->backup_unique_code,'grade_categories', $iteminstance);
-                                        $dbrec->iteminstance = $category->new_id;
-                                    } else {
-                                        // otherwise we can safely ignore this grade item and subsequent
-                                        // grade_raws, grade_finals etc
-                                        continue;
-                                    }
-                                } elseif ($dbrec->itemtype == 'course') { // We don't restore course type to avoid duplicate course items
-                                    if ($restoreall) {
-                                        // TODO any special code needed here to restore course item without duplicating it?
-                                        // find the course category with depth 1, and course id = current course id
-                                        // this would have been already restored
-
-                                        $cat = $DB->get_record('grade_categories', array('depth'=>1, 'courseid'=>$restore->course_id));
-                                        $dbrec->iteminstance = $cat->id;
-
-                                    } else {
-                                        $counter++;
-                                        continue;
-                                    }
-                                }
-
-                                $dbrec->itemnumber = backup_todb($info['GRADE_ITEM_HISTORY']['#']['ITEMNUMBER']['0']['#']);
-                                $dbrec->iteminfo = backup_todb($info['GRADE_ITEM_HISTORY']['#']['ITEMINFO']['0']['#']);
-                                $dbrec->idnumber = backup_todb($info['GRADE_ITEM_HISTORY']['#']['IDNUMBER']['0']['#']);
-                                $dbrec->calculation = backup_todb($info['GRADE_ITEM_HISTORY']['#']['CALCULATION']['0']['#']);
-                                $dbrec->gradetype = backup_todb($info['GRADE_ITEM_HISTORY']['#']['GRADETYPE']['0']['#']);
-                                $dbrec->grademax = backup_todb($info['GRADE_ITEM_HISTORY']['#']['GRADEMAX']['0']['#']);
-                                $dbrec->grademin = backup_todb($info['GRADE_ITEM_HISTORY']['#']['GRADEMIN']['0']['#']);
-                                if ($oldobj = backup_getid($restore->backup_unique_code,"scale", backup_todb($info['GRADE_ITEM_HISTORY']['#']['SCALEID']['0']['#']))) {
-                                    // scaleid is optional
-                                    $dbrec->scaleid = $oldobj->new_id;
-                                }
-                                if ($oldobj = backup_getid($restore->backup_unique_code,"grade_outcomes", backup_todb($info['GRADE_ITEM_HISTORY']['#']['OUTCOMEID']['0']['#']))) {
-                                    // outcome is optional
-                                    $dbrec->outcomeid = $oldobj->new_id;
-                                }
-                                $dbrec->gradepass = backup_todb($info['GRADE_ITEM_HISTORY']['#']['GRADEPASS']['0']['#']);
-                                $dbrec->multfactor = backup_todb($info['GRADE_ITEM_HISTORY']['#']['MULTFACTOR']['0']['#']);
-                                $dbrec->plusfactor = backup_todb($info['GRADE_ITEM_HISTORY']['#']['PLUSFACTOR']['0']['#']);
-                                $dbrec->aggregationcoef = backup_todb($info['GRADE_ITEM_HISTORY']['#']['AGGREGATIONCOEF']['0']['#']);
-                                $dbrec->sortorder = backup_todb($info['GRADE_ITEM_HISTORY']['#']['SORTORDER']['0']['#']);
-                                $dbrec->display = backup_todb($info['GRADE_ITEM_HISTORY']['#']['DISPLAY']['0']['#']);
-                                $dbrec->decimals = backup_todb($info['GRADE_ITEM_HISTORY']['#']['DECIMALS']['0']['#']);
-                                $dbrec->hidden = backup_todb($info['GRADE_ITEM_HISTORY']['#']['HIDDEN']['0']['#']);
-                                $dbrec->locked = backup_todb($info['GRADE_ITEM_HISTORY']['#']['LOCKED']['0']['#']);
-                                $dbrec->locktime = backup_todb($info['GRADE_ITEM_HISTORY']['#']['LOCKTIME']['0']['#']);
-                                $dbrec->needsupdate = backup_todb($info['GRADE_ITEM_HISTORY']['#']['NEEDSUPDATE']['0']['#']);
-
-                                $DB->insert_record('grade_items_history', $dbrec);
-                                unset($dbrec);
-
-                            }
-                            //Increment counters
-                            $counter++;
-                            //Do some output
-                            if ($counter % 1 == 0) {
-                                if (!defined('RESTORE_SILENTLY')) {
-                                    echo ".";
-                                    if ($counter % 20 == 0) {
-                                        echo "<br />";
-                                    }
-                                }
-                                backup_flush(300);
-                            }
-                        }
-                    }
-                }
-            }
-
-            // process histories
-            if ($gohcount && $status) {
-                if (!defined('RESTORE_SILENTLY')) {
-                    echo '<li>'.get_string('gradeoutcomeshistory','grades').'</li>';
-                }
-                $counter = 0;
-                while ($counter < $gohcount) {
-                    //Fetch recordset_size records in each iteration
-                    $recs = $DB->get_records("backup_ids", array('table_name'=>'grade_outcomes_history', 'backup_code'=>$restore->backup_unique_code),
-                                                "old_id",
-                                                "old_id",
-                                                $counter,
-                                                $recordset_size);
-                    if ($recs) {
-                        foreach ($recs as $rec) {
-                            //Get the full record from backup_ids
-                            $data = backup_getid($restore->backup_unique_code,'grade_outcomes_history',$rec->old_id);
-                            if ($data) {
-                                //Now get completed xmlized object
-                                $info = $data->info;
-                                //traverse_xmlize($info);                            //Debug
-                                //print_object ($GLOBALS['traverse_array']);         //Debug
-                                //$GLOBALS['traverse_array']="";                     //Debug
-
-                                $oldobj = backup_getid($restore->backup_unique_code,"grade_outcomes", backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['OLDID']['0']['#']));
-                                if (empty($oldobj->new_id)) {
-                                    // if the old object is not being restored, can't restoring its history
-                                    $counter++;
-                                    continue;
-                                }
-                                $dbrec->oldid = $oldobj->new_id;
-                                $dbrec->action = backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['ACTION']['0']['#']);
-                                $dbrec->source = backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['SOURCE']['0']['#']);
-                                $dbrec->timemodified = backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['TIMEMODIFIED']['0']['#']);
-                                if ($oldobj = backup_getid($restore->backup_unique_code,"user", backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['LOGGEDUSER']['0']['#']))) {
-                                    $dbrec->loggeduser = $oldobj->new_id;
-                                }
-                                $dbrec->courseid = $restore->course_id;
-                                $dbrec->shortname = backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['SHORTNAME']['0']['#']);
-                                $dbrec->fullname= backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['FULLNAME']['0']['#']);
-                                $oldobj = backup_getid($restore->backup_unique_code,"scale", backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['SCALEID']['0']['#']));
-                                $dbrec->scaleid = $oldobj->new_id;
-                                $dbrec->description = backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['DESCRIPTION']['0']['#']);
-
-                                $DB->insert_record('grade_outcomes_history', $dbrec);
-                                unset($dbrec);
-
-                            }
-                            //Increment counters
-                            $counter++;
-                            //Do some output
-                            if ($counter % 1 == 0) {
-                                if (!defined('RESTORE_SILENTLY')) {
-                                    echo ".";
-                                    if ($counter % 20 == 0) {
-                                        echo "<br />";
-                                    }
-                                }
-                                backup_flush(300);
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        if (!defined('RESTORE_SILENTLY')) {
-        //End ul
-            echo '</ul>';
-        }
-        return $status;
-    }
-
-    //This function creates all the structures messages and contacts
-    function restore_create_messages($restore,$xml_file) {
-        global $CFG, $DB;
-
-        $status = true;
-        //Check it exists
-        if (!file_exists($xml_file)) {
-            $status = false;
-        }
-        //Get info from xml
-        if ($status) {
-            //info will contain the id and name of every table
-            //(message, message_read and message_contacts)
-            //in backup_ids->info will be the real info (serialized)
-            $info = restore_read_xml_messages($restore,$xml_file);
-
-            //If we have info, then process messages & contacts
-            if ($info > 0) {
-                //Count how many we have
-                $unreadcount  = $DB->count_records ('backup_ids', array('backup_code'=>$restore->backup_unique_code, 'table_name'=>'message'));
-                $readcount    = $DB->count_records ('backup_ids', array('backup_code'=>$restore->backup_unique_code, 'table_name'=>'message_read'));
-                $contactcount = $DB->count_records ('backup_ids', array('backup_code'=>$restore->backup_unique_code, 'table_name'=>'message_contacts'));
-                if ($unreadcount || $readcount || $contactcount) {
-                    //Start ul
-                    if (!defined('RESTORE_SILENTLY')) {
-                        echo '<ul>';
-                    }
-                    //Number of records to get in every chunk
-                    $recordset_size = 4;
-
-                    //Process unread
-                    if ($unreadcount) {
-                        if (!defined('RESTORE_SILENTLY')) {
-                            echo '<li>'.get_string('unreadmessages','message').'</li>';
-                        }
-                        $counter = 0;
-                        while ($counter < $unreadcount) {
-                            //Fetch recordset_size records in each iteration
-                            $recs = $DB->get_records("backup_ids", array('table_name'=>'message', 'backup_code'=>$restore->backup_unique_code),"old_id","old_id",$counter,$recordset_size);
-                            if ($recs) {
-                                foreach ($recs as $rec) {
-                                    //Get the full record from backup_ids
-                                    $data = backup_getid($restore->backup_unique_code,"message",$rec->old_id);
-                                    if ($data) {
-                                        //Now get completed xmlized object
-                                        $info = $data->info;
-                                        //traverse_xmlize($info);                            //Debug
-                                        //print_object ($GLOBALS['traverse_array']);         //Debug
-                                        //$GLOBALS['traverse_array']="";                     //Debug
-                                        //Now build the MESSAGE record structure
-                                        $dbrec = new object();
-                                        $dbrec->useridfrom = backup_todb($info['MESSAGE']['#']['USERIDFROM']['0']['#']);
-                                        $dbrec->useridto = backup_todb($info['MESSAGE']['#']['USERIDTO']['0']['#']);
-                                        $dbrec->message = backup_todb($info['MESSAGE']['#']['MESSAGE']['0']['#']);
-                                        $dbrec->format = backup_todb($info['MESSAGE']['#']['FORMAT']['0']['#']);
-                                        $dbrec->timecreated = backup_todb($info['MESSAGE']['#']['TIMECREATED']['0']['#']);
-                                        $dbrec->messagetype = backup_todb($info['MESSAGE']['#']['MESSAGETYPE']['0']['#']);
-                                        //We have to recode the useridfrom field
-                                        $user = backup_getid($restore->backup_unique_code,"user",$dbrec->useridfrom);
-                                        if ($user) {
-                                            //echo "User ".$dbrec->useridfrom." to user ".$user->new_id."<br />";   //Debug
-                                            $dbrec->useridfrom = $user->new_id;
-                                        }
-                                        //We have to recode the useridto field
-                                        $user = backup_getid($restore->backup_unique_code,"user",$dbrec->useridto);
-                                        if ($user) {
-                                            //echo "User ".$dbrec->useridto." to user ".$user->new_id."<br />";   //Debug
-                                            $dbrec->useridto = $user->new_id;
-                                        }
-                                        //Check if the record doesn't exist in DB!
-                                        $exist = $DB->get_record('message', array('useridfrom'=>$dbrec->useridfrom,
-                                                                                  'useridto'=>$dbrec->useridto,
-                                                                                  'timecreated'=>$dbrec->timecreated));
-                                        if (!$exist) {
-                                            //Not exist. Insert
-                                            $status = $DB->insert_record('message',$dbrec);
-                                        } else {
-                                            //Duplicate. Do nothing
-                                        }
-                                    }
-                                    //Do some output
-                                    $counter++;
-                                    if ($counter % 10 == 0) {
-                                        if (!defined('RESTORE_SILENTLY')) {
-                                            echo ".";
-                                            if ($counter % 200 == 0) {
-                                                echo "<br />";
-                                            }
-                                        }
-                                        backup_flush(300);
-                                    }
-                                }
-                            }
-                        }
-                    }
-
-                    //Process read
-                    if ($readcount) {
-                        if (!defined('RESTORE_SILENTLY')) {
-                            echo '<li>'.get_string('readmessages','message').'</li>';
-                        }
-                        $counter = 0;
-                        while ($counter < $readcount) {
-                            //Fetch recordset_size records in each iteration
-                            $recs = $DB->get_records("backup_ids", array('table_name'=>'message_read', 'backup_code'=>$restore->backup_unique_code),"old_id","old_id",$counter,$recordset_size);
-                            if ($recs) {
-                                foreach ($recs as $rec) {
-                                    //Get the full record from backup_ids
-                                    $data = backup_getid($restore->backup_unique_code,"message_read",$rec->old_id);
-                                    if ($data) {
-                                        //Now get completed xmlized object
-                                        $info = $data->info;
-                                        //traverse_xmlize($info);                            //Debug
-                                        //print_object ($GLOBALS['traverse_array']);         //Debug
-                                        //$GLOBALS['traverse_array']="";                     //Debug
-                                        //Now build the MESSAGE_READ record structure
-                                        $dbrec->useridfrom = backup_todb($info['MESSAGE']['#']['USERIDFROM']['0']['#']);
-                                        $dbrec->useridto = backup_todb($info['MESSAGE']['#']['USERIDTO']['0']['#']);
-                                        $dbrec->message = backup_todb($info['MESSAGE']['#']['MESSAGE']['0']['#']);
-                                        $dbrec->format = backup_todb($info['MESSAGE']['#']['FORMAT']['0']['#']);
-                                        $dbrec->timecreated = backup_todb($info['MESSAGE']['#']['TIMECREATED']['0']['#']);
-                                        $dbrec->messagetype = backup_todb($info['MESSAGE']['#']['MESSAGETYPE']['0']['#']);
-                                        $dbrec->timeread = backup_todb($info['MESSAGE']['#']['TIMEREAD']['0']['#']);
-                                        $dbrec->mailed = backup_todb($info['MESSAGE']['#']['MAILED']['0']['#']);
-                                        //We have to recode the useridfrom field
-                                        $user = backup_getid($restore->backup_unique_code,"user",$dbrec->useridfrom);
-                                        if ($user) {
-                                            //echo "User ".$dbrec->useridfrom." to user ".$user->new_id."<br />";   //Debug
-                                            $dbrec->useridfrom = $user->new_id;
-                                        }
-                                        //We have to recode the useridto field
-                                        $user = backup_getid($restore->backup_unique_code,"user",$dbrec->useridto);
-                                        if ($user) {
-                                            //echo "User ".$dbrec->useridto." to user ".$user->new_id."<br />";   //Debug
-                                            $dbrec->useridto = $user->new_id;
-                                        }
-                                        //Check if the record doesn't exist in DB!
-                                        $exist = $DB->get_record('message_read', array('useridfrom'=>$dbrec->useridfrom,
-                                                                                       'useridto'=>$dbrec->useridto,
-                                                                                       'timecreated'=>$dbrec->timecreated));
-                                        if (!$exist) {
-                                            //Not exist. Insert
-                                            $status = $DB->insert_record('message_read',$dbrec);
-                                        } else {
-                                            //Duplicate. Do nothing
-                                        }
-                                    }
-                                    //Do some output
-                                    $counter++;
-                                    if ($counter % 10 == 0) {
-                                        if (!defined('RESTORE_SILENTLY')) {
-                                            echo ".";
-                                            if ($counter % 200 == 0) {
-                                                echo "<br />";
-                                            }
-                                        }
-                                        backup_flush(300);
-                                    }
-                                }
-                            }
-                        }
-                    }
-
-                    //Process contacts
-                    if ($contactcount) {
-                        if (!defined('RESTORE_SILENTLY')) {
-                            echo '<li>'.moodle_strtolower(get_string('contacts','message')).'</li>';
-                        }
-                        $counter = 0;
-                        while ($counter < $contactcount) {
-                            //Fetch recordset_size records in each iteration
-                            $recs = $DB->get_records("backup_ids", array('table_name'=>'message_contacts', 'backup_code'=>$restore->backup_unique_code),"old_id","old_id",$counter,$recordset_size);
-                            if ($recs) {
-                                foreach ($recs as $rec) {
-                                    //Get the full record from backup_ids
-                                    $data = backup_getid($restore->backup_unique_code,"message_contacts",$rec->old_id);
-                                    if ($data) {
-                                        //Now get completed xmlized object
-                                        $info = $data->info;
-                                        //traverse_xmlize($info);                            //Debug
-                                        //print_object ($GLOBALS['traverse_array']);         //Debug
-                                        //$GLOBALS['traverse_array']="";                     //Debug
-                                        //Now build the MESSAGE_CONTACTS record structure
-                                        $dbrec->userid = backup_todb($info['CONTACT']['#']['USERID']['0']['#']);
-                                        $dbrec->contactid = backup_todb($info['CONTACT']['#']['CONTACTID']['0']['#']);
-                                        $dbrec->blocked = backup_todb($info['CONTACT']['#']['BLOCKED']['0']['#']);
-                                        //We have to recode the userid field
-                                        $user = backup_getid($restore->backup_unique_code,"user",$dbrec->userid);
-                                        if ($user) {
-                                            //echo "User ".$dbrec->userid." to user ".$user->new_id."<br />";   //Debug
-                                            $dbrec->userid = $user->new_id;
-                                        }
-                                        //We have to recode the contactid field
-                                        $user = backup_getid($restore->backup_unique_code,"user",$dbrec->contactid);
-                                        if ($user) {
-                                            //echo "User ".$dbrec->contactid." to user ".$user->new_id."<br />";   //Debug
-                                            $dbrec->contactid = $user->new_id;
-                                        }
-                                        //Check if the record doesn't exist in DB!
-                                        $exist = $DB->get_record('message_contacts', array('userid'=>$dbrec->userid,
-                                                                                           'contactid'=>$dbrec->contactid));
-                                        if (!$exist) {
-                                            //Not exist. Insert
-                                            $status = $DB->insert_record('message_contacts',$dbrec);
-                                        } else {
-                                            //Duplicate. Do nothing
-                                        }
-                                    }
-                                    //Do some output
-                                    $counter++;
-                                    if ($counter % 10 == 0) {
-                                        if (!defined('RESTORE_SILENTLY')) {
-                                            echo ".";
-                                            if ($counter % 200 == 0) {
-                                                echo "<br />";
-                                            }
-                                        }
-                                        backup_flush(300);
-                                    }
-                                }
-                            }
-                        }
-                    }
-                    if (!defined('RESTORE_SILENTLY')) {
-                        //End ul
-                        echo '</ul>';
-                    }
-                }
-            }
-        }
-
-       return $status;
-    }
-
-    //This function creates all the structures for blogs and blog tags
-    function restore_create_blogs($restore,$xml_file) {
-        global $CFG, $DB;
-
-        $status = true;
-        //Check it exists
-        if (!file_exists($xml_file)) {
-            $status = false;
-        }
-        //Get info from xml
-        if ($status) {
-            //info will contain the number of blogs in the backup file
-            //in backup_ids->info will be the real info (serialized)
-            $info = restore_read_xml_blogs($restore,$xml_file);
-
-            //If we have info, then process blogs & blog_tags
-            if ($info > 0) {
-                //Count how many we have
-                $blogcount = $DB->count_records('backup_ids', array('backup_code'=>$restore->backup_unique_code, 'table_name'=>'blog'));
-                if ($blogcount) {
-                    //Number of records to get in every chunk
-                    $recordset_size = 4;
-
-                    //Process blog
-                    if ($blogcount) {
-                        $counter = 0;
-                        while ($counter < $blogcount) {
-                            //Fetch recordset_size records in each iteration
-                            $recs = $DB->get_records("backup_ids", array("table_name"=>'blog', 'backup_code'=>$restore->backup_unique_code),"old_id","old_id",$counter,$recordset_size);
-                            if ($recs) {
-                                foreach ($recs as $rec) {
-                                    //Get the full record from backup_ids
-                                    $data = backup_getid($restore->backup_unique_code,"blog",$rec->old_id);
-                                    if ($data) {
-                                        //Now get completed xmlized object
-                                        $info = $data->info;
-                                        //traverse_xmlize($info);                            //Debug
-                                        //print_object ($GLOBALS['traverse_array']);         //Debug
-                                        //$GLOBALS['traverse_array']="";                     //Debug
-                                        //Now build the BLOG record structure
-                                        $dbrec = new object();
-                                        $dbrec->module = backup_todb($info['BLOG']['#']['MODULE']['0']['#']);
-                                        $dbrec->userid = backup_todb($info['BLOG']['#']['USERID']['0']['#']);
-                                        $dbrec->courseid = backup_todb($info['BLOG']['#']['COURSEID']['0']['#']);
-                                        $dbrec->groupid = backup_todb($info['BLOG']['#']['GROUPID']['0']['#']);
-                                        $dbrec->moduleid = backup_todb($info['BLOG']['#']['MODULEID']['0']['#']);
-                                        $dbrec->coursemoduleid = backup_todb($info['BLOG']['#']['COURSEMODULEID']['0']['#']);
-                                        $dbrec->subject = backup_todb($info['BLOG']['#']['SUBJECT']['0']['#']);
-                                        $dbrec->summary = backup_todb($info['BLOG']['#']['SUMMARY']['0']['#']);
-                                        $dbrec->content = backup_todb($info['BLOG']['#']['CONTENT']['0']['#']);
-                                        $dbrec->uniquehash = backup_todb($info['BLOG']['#']['UNIQUEHASH']['0']['#']);
-                                        $dbrec->rating = backup_todb($info['BLOG']['#']['RATING']['0']['#']);
-                                        $dbrec->format = backup_todb($info['BLOG']['#']['FORMAT']['0']['#']);
-                                        $dbrec->attachment = backup_todb($info['BLOG']['#']['ATTACHMENT']['0']['#']);
-                                        $dbrec->publishstate = backup_todb($info['BLOG']['#']['PUBLISHSTATE']['0']['#']);
-                                        $dbrec->lastmodified = backup_todb($info['BLOG']['#']['LASTMODIFIED']['0']['#']);
-                                        $dbrec->created = backup_todb($info['BLOG']['#']['CREATED']['0']['#']);
-                                        $dbrec->usermodified = backup_todb($info['BLOG']['#']['USERMODIFIED']['0']['#']);
-
-                                        //We have to recode the userid field
-                                        $user = backup_getid($restore->backup_unique_code,"user",$dbrec->userid);
-                                        if ($user) {
-                                            //echo "User ".$dbrec->userid." to user ".$user->new_id."<br />";   //Debug
-                                            $dbrec->userid = $user->new_id;
-                                        }
-
-                                        //Check if the record doesn't exist in DB!
-                                        $exist = $DB->get_record('post', array('userid'=>$dbrec->userid,
-                                                                               'subject'=>$dbrec->subject,
-                                                                               'created'=>$dbrec->created));
-                                        $newblogid = 0;
-                                        if (!$exist) {
-                                            //Not exist. Insert
-                                            $newblogid = $DB->insert_record('post',$dbrec);
-                                        }
-
-                                        //Going to restore related tags. Check they are enabled and we have inserted a blog
-                                        if ($CFG->usetags && $newblogid) {
-                                            //Look for tags in this blog
-                                            if (isset($info['BLOG']['#']['BLOG_TAGS']['0']['#']['BLOG_TAG'])) {
-                                                $tagsarr = $info['BLOG']['#']['BLOG_TAGS']['0']['#']['BLOG_TAG'];
-                                                //Iterate over tags
-                                                $tags = array();
-                                                for($i = 0; $i < sizeof($tagsarr); $i++) {
-                                                    $tag_info = $tagsarr[$i];
-                                                    ///traverse_xmlize($tag_info);                        //Debug
-                                                    ///print_object ($GLOBALS['traverse_array']);         //Debug
-                                                    ///$GLOBALS['traverse_array']="";                     //Debug
-
-                                                    $name = backup_todb($tag_info['#']['NAME']['0']['#']);
-                                                    $rawname = backup_todb($tag_info['#']['RAWNAME']['0']['#']);
-
-                                                    $tags[] = $rawname;  //Rawname is all we need
-                                                }
-                                                tag_set('post', $newblogid, $tags); //Add all the tags in one API call
-                                            }
-                                        }
-                                    }
-                                    //Do some output
-                                    $counter++;
-                                    if ($counter % 10 == 0) {
-                                        if (!defined('RESTORE_SILENTLY')) {
-                                            echo ".";
-                                            if ($counter % 200 == 0) {
-                                                echo "<br />";
-                                            }
-                                        }
-                                        backup_flush(300);
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        return $status;
-    }
-
-    //This function creates all the categories and questions
-    //from xml
-    function restore_create_questions($restore,$xml_file) {
-        global $CFG;
-
-        $status = true;
-        //Check it exists
-        if (!file_exists($xml_file)) {
-            $status = false;
-        }
-        //Get info from xml
-        if ($status) {
-            //info will contain the old_id of every category
-            //in backup_ids->info will be the real info (serialized)
-            $info = restore_read_xml_questions($restore,$xml_file);
-        }
-        //Now, if we have anything in info, we have to restore that
-        //categories/questions
-        if ($info) {
-            if ($info !== true) {
-                $status = $status &&  restore_question_categories($info, $restore);
-            }
-        } else {
-            $status = false;
-        }
-        return $status;
-    }
-
-    //This function creates all the course events
-    function restore_create_events($restore,$xml_file) {
-        global $DB;
-
-        global $CFG, $SESSION;
-
-        $status = true;
-        //Check it exists
-        if (!file_exists($xml_file)) {
-            $status = false;
-        }
-        //Get info from xml
-        if ($status) {
-            //events will contain the old_id of every event
-            //in backup_ids->info will be the real info (serialized)
-            $events = restore_read_xml_events($restore,$xml_file);
-        }
-
-        //Get admin->id for later use
-        $admin = get_admin();
-        $adminid = $admin->id;
-
-        //Now, if we have anything in events, we have to restore that
-        //events
-        if ($events) {
-            if ($events !== true) {
-                //Iterate over each event
-                foreach ($events as $event) {
-                    //Get record from backup_ids
-                    $data = backup_getid($restore->backup_unique_code,"event",$event->id);
-                    //Init variables
-                    $create_event = false;
-
-                    if ($data) {
-                        //Now get completed xmlized object
-                        $info = $data->info;
-                        //traverse_xmlize($info);                                                                     //Debug
-                        //print_object ($GLOBALS['traverse_array']);                                                  //Debug
-                        //$GLOBALS['traverse_array']="";                                                              //Debug
-
-                        //if necessary, write to restorelog and adjust date/time fields
-                        if ($restore->course_startdateoffset) {
-                            restore_log_date_changes('Events', $restore, $info['EVENT']['#'], array('TIMESTART'));
-                        }
-
-                        //Now build the EVENT record structure
-                        $eve->name = backup_todb($info['EVENT']['#']['NAME']['0']['#']);
-                        $eve->description = backup_todb($info['EVENT']['#']['DESCRIPTION']['0']['#']);
-                        $eve->format = backup_todb($info['EVENT']['#']['FORMAT']['0']['#']);
-                        $eve->courseid = $restore->course_id;
-                        $eve->groupid = backup_todb($info['EVENT']['#']['GROUPID']['0']['#']);
-                        $eve->userid = backup_todb($info['EVENT']['#']['USERID']['0']['#']);
-                        $eve->repeatid = backup_todb($info['EVENT']['#']['REPEATID']['0']['#']);
-                        $eve->modulename = "";
-                        if (!empty($info['EVENT']['#']['MODULENAME'])) {
-                            $eve->modulename = backup_todb($info['EVENT']['#']['MODULENAME']['0']['#']);
-                        }
-                        $eve->instance = 0;
-                        $eve->eventtype = backup_todb($info['EVENT']['#']['EVENTTYPE']['0']['#']);
-                        $eve->timestart = backup_todb($info['EVENT']['#']['TIMESTART']['0']['#']);
-                        $eve->timeduration = backup_todb($info['EVENT']['#']['TIMEDURATION']['0']['#']);
-                        $eve->visible = backup_todb($info['EVENT']['#']['VISIBLE']['0']['#']);
-                        $eve->timemodified = backup_todb($info['EVENT']['#']['TIMEMODIFIED']['0']['#']);
-
-                        //Now search if that event exists (by name, description, timestart fields) in
-                        //restore->course_id course
-                        //Going to compare LOB columns so, use the cross-db sql_compare_text() in both sides.
-                        $compare_description_clause = $DB->sql_compare_text('description')  . "=" .  $DB->sql_compare_text("'" . $eve->description . "'");
-                        $eve_db = $DB->get_record_select('event',
-                            "courseid = ? AND name = ? AND $compare_description_clause AND timestart = ?",
-                            array($eve->courseid, $eve->name, $eve->timestart));
-                        //If it doesn't exist, create
-                        if (!$eve_db) {
-                            $create_event = true;
-                        }
-                        //If we must create the event
-                        if ($create_event) {
-
-                            //We must recode the userid
-                            $user = backup_getid($restore->backup_unique_code,"user",$eve->userid);
-                            if ($user) {
-                                $eve->userid = $user->new_id;
-                            } else {
-                                //Assign it to admin
-                                $eve->userid = $adminid;
-                            }
-
-                            //We have to recode the groupid field
-                            $group = backup_getid($restore->backup_unique_code,"groups",$eve->groupid);
-                            if ($group) {
-                                $eve->groupid = $group->new_id;
-                            } else {
-                                //Assign it to group 0
-                                $eve->groupid = 0;
-                            }
-
-                            //The structure is equal to the db, so insert the event
-                            $newid = $DB->insert_record ("event",$eve);
-
-                            //We must recode the repeatid if the event has it
-                            //The repeatid now refers to the id of the original event. (see Bug#5956)
-                            if ($newid && !empty($eve->repeatid)) {
-                                $repeat_rec = backup_getid($restore->backup_unique_code,"event_repeatid",$eve->repeatid);
-                                if ($repeat_rec) {    //Exists, so use it...
-                                    $eve->repeatid = $repeat_rec->new_id;
-                                } else {              //Doesn't exists, calculate the next and save it
-                                    $oldrepeatid = $eve->repeatid;
-                                    $eve->repeatid = $newid;
-                                    backup_putid($restore->backup_unique_code,"event_repeatid", $oldrepeatid, $eve->repeatid);
-                                }
-                                $eve->id = $newid;
-                                // update the record to contain the correct repeatid
-                                $DB->update_record('event',$eve);
-                            }
-                        } else {
-                            //get current event id
-                            $newid = $eve_db->id;
-                        }
-                        if ($newid) {
-                            //We have the newid, update backup_ids
-                            backup_putid($restore->backup_unique_code,"event",
-                                         $event->id, $newid);
-                        }
-                    }
-                }
-            }
-        } else {
-            $status = false;
-        }
-        return $status;
-    }
-
-    //This function decode things to make restore multi-site fully functional
-    //It does this conversions:
-    //    - $@FILEPHP@$ ---|------------> $CFG->wwwroot/file.php/courseid (slasharguments on)
-    //                     |------------> $CFG->wwwroot/file.php?file=/courseid (slasharguments off)
-    //
-    //    - $@SLASH@$ --|---------------> / (slasharguments on)
-    //                  |---------------> %2F (slasharguments off)
-    //
-    //    - $@FORCEDOWNLOAD@$ --|-------> ?forcedownload=1 (slasharguments on)
-    //                          |-------> &amp;forcedownload=1(slasharguments off)
-    //Note: Inter-activities linking is being implemented as a final
-    //step in the restore execution, because we need to have it
-    //finished to know all the oldid, newid equivaleces
-    function restore_decode_absolute_links($content) {
-        global $CFG, $restore;
-        require_once($CFG->libdir.'/filelib.php');
-
-    /// MDL-14072: Prevent NULLs, empties and numbers to be processed by the
-    /// heavy interlinking. Just a few cpu cycles saved.
-        if ($content === NULL) {
-            return NULL;
-        } else if ($content === '') {
-            return '';
-        } else if (is_numeric($content)) {
-            return $content;
-        }
-
-        //Now decode wwwroot and file.php calls
-        $search = array ("$@FILEPHP@$");
-        $replace = array(get_file_url($restore->course_id));
-        $result = str_replace($search,$replace,$content);
-
-        //Now $@SLASH@$ and $@FORCEDOWNLOAD@$ MDL-18799
-        $search = array('$@SLASH@$', '$@FORCEDOWNLOAD@$');
-        if ($CFG->slasharguments) {
-            $replace = array('/', '?forcedownload=1');
-        } else {
-            $replace = array('%2F', '&amp;forcedownload=1');
-        }
-        $result = str_replace($search, $replace, $result);
-
-        if ($result != $content && debugging()) {                                  //Debug
-            if (!defined('RESTORE_SILENTLY')) {
-                echo '<br /><hr />'.s($content).'<br />changed to<br />'.s($result).'<hr /><br />';        //Debug
-            }
-        }                                                                            //Debug
-
-        return $result;
-    }
-
-    //This function restores the userfiles from the temp (user_files) directory to the
-    //dataroot/users directory
-    function restore_user_files($restore) {
-
-        global $CFG;
-
-        $status = true;
-
-        $counter = 0;
-
-        // 'users' is the old users folder, 'user' is the new one, with a new hierarchy. Detect which one is here and treat accordingly
-        //in CFG->dataroot
-        $dest_dir = $CFG->dataroot."/user";
-        $status = check_dir_exists($dest_dir,true);
-
-        //Now, we iterate over "user_files" records to check if that user dir must be
-        //copied (and renamed) to the "users" dir.
-        $rootdir = $CFG->dataroot."/temp/backup/".$restore->backup_unique_code."/user_files";
-
-        //Check if directory exists
-        $userlist = array();
-
-        if (is_dir($rootdir) && ($list = list_directories ($rootdir))) {
-            $counter = 0;
-            foreach ($list as $dir) {
-                // If there are directories in this folder, we are in the new user hierarchy
-                if ($newlist = list_directories("$rootdir/$dir")) {
-                    foreach ($newlist as $olduserid) {
-                        $userlist[$olduserid] = "$rootdir/$dir/$olduserid";
-                    }
-                } else {
-                    $userlist[$dir] = "$rootdir/$dir";
-                }
-            }
-
-            foreach ($userlist as $olduserid => $backup_location) {
-                //Look for dir like username in backup_ids
-                //If that user exists in backup_ids
-                if ($user = backup_getid($restore->backup_unique_code,"user",$olduserid)) {
-                    //Only if user has been created now or if it existed previously, but he hasn't got an image (see bug 1123)
-                    //TODO: user images are now in new file storage, old code deleted
-                }
-            }
-        }
-        //If status is ok and whe have dirs created, returns counter to inform
-        if ($status and $counter) {
-            return $counter;
-        } else {
-            return $status;
-        }
-    }
-
-    //This function restores the groupfiles from the temp (group_files) directory to the
-    //dataroot/groups directory
-    function restore_group_files($restore) {
-        global $CFG, $DB;
-
-        $status = true;
-
-        $counter = 0;
-
-        //First, we check to "groups" exists and create is as necessary
-        //in CFG->dataroot
-        $dest_dir = $CFG->dataroot.'/groups';
-        $status = check_dir_exists($dest_dir,true);
-
-        //Now, we iterate over "group_files" records to check if that user dir must be
-        //copied (and renamed) to the "groups" dir.
-        $rootdir = $CFG->dataroot."/temp/backup/".$restore->backup_unique_code."/group_files";
-        //Check if directory exists
-        if (is_dir($rootdir)) {
-            $list = list_directories ($rootdir);
-            if ($list) {
-                //Iterate
-                $counter = 0;
-                foreach ($list as $dir) {
-                    //Look for dir like groupid in backup_ids
-                    $data = $DB->get_record ("backup_ids", array("backup_code"=>$restore->backup_unique_code,
-                                                     "table_name"=>"groups",
-                                                     "old_id"=>$dir));
-                    //If that group exists in backup_ids
-                    if ($data) {
-                        if (!file_exists($dest_dir."/".$data->new_id)) {
-                            $status = backup_copy_file($rootdir."/".$dir, $dest_dir."/".$data->new_id,true);
-                            $counter ++;
-                        }
-                        //Do some output
-                        if ($counter % 2 == 0) {
-                            if (!defined('RESTORE_SILENTLY')) {
-                                echo ".";
-                                if ($counter % 40 == 0) {
-                                    echo "<br />";
-                                }
-                            }
-                            backup_flush(300);
-                        }
-                    }
-                }
-            }
-        }
-        //If status is ok and whe have dirs created, returns counter to inform
-        if ($status and $counter) {
-            return $counter;
-        } else {
-            return $status;
-        }
-    }
-
-    //This function restores the course files from the temp (course_files) directory to the
-    //dataroot/course_id directory
-    function restore_course_files($restore) {
-        global $CFG;
-
-        $status = true;
-
-        $counter = 0;
-
-        //First, we check to "course_id" exists and create is as necessary
-        //in CFG->dataroot
-        $dest_dir = $CFG->dataroot."/".$restore->course_id;
-        $status = check_dir_exists($dest_dir,true);
-
-        //Now, we iterate over "course_files" records to check if that file/dir must be
-        //copied to the "dest_dir" dir.
-        $rootdir = $CFG->dataroot."/temp/backup/".$restore->backup_unique_code."/course_files";
-        //Check if directory exists
-        if (is_dir($rootdir)) {
-            $list = list_directories_and_files ($rootdir);
-            if ($list) {
-                //Iterate
-                $counter = 0;
-                foreach ($list as $dir) {
-                    //Copy the dir to its new location
-                    //Only if destination file/dir doesn exists
-                    if (!file_exists($dest_dir."/".$dir)) {
-                        $status = backup_copy_file($rootdir."/".$dir,
-                                      $dest_dir."/".$dir,true);
-                        $counter ++;
-                    }
-                    //Do some output
-                    if ($counter % 2 == 0) {
-                        if (!defined('RESTORE_SILENTLY')) {
-                            echo ".";
-                            if ($counter % 40 == 0) {
-                                echo "<br />";
-                            }
-                        }
-                        backup_flush(300);
-                    }
-                }
-            }
-        }
-        //If status is ok and whe have dirs created, returns counter to inform
-        if ($status and $counter) {
-            return $counter;
-        } else {
-            return $status;
-        }
-    }
-
-    //This function restores the site files from the temp (site_files) directory to the
-    //dataroot/SITEID directory
-    function restore_site_files($restore) {
-        global $CFG;
-
-        $status = true;
-
-        $counter = 0;
-
-        //First, we check to "course_id" exists and create is as necessary
-        //in CFG->dataroot
-        $dest_dir = $CFG->dataroot."/".SITEID;
-        $status = check_dir_exists($dest_dir,true);
-
-        //Now, we iterate over "site_files" files to check if that file/dir must be
-        //copied to the "dest_dir" dir.
-        $rootdir = $CFG->dataroot."/temp/backup/".$restore->backup_unique_code."/site_files";
-        //Check if directory exists
-        if (is_dir($rootdir)) {
-            $list = list_directories_and_files ($rootdir);
-            if ($list) {
-                //Iterate
-                $counter = 0;
-                foreach ($list as $dir) {
-                    //no need to deal with 'maintenance.html' here anymore - MDL-18594
-                    //Copy the dir to its new location
-                    //Only if destination file/dir doesn exists
-                    if (!file_exists($dest_dir."/".$dir)) {
-                        $status = backup_copy_file($rootdir."/".$dir,
-                                      $dest_dir."/".$dir,true);
-                        $counter ++;
-                    }
-                    //Do some output
-                    if ($counter % 2 == 0) {
-                        if (!defined('RESTORE_SILENTLY')) {
-                            echo ".";
-                            if ($counter % 40 == 0) {
-                                echo "<br />";
-                            }
-                        }
-                        backup_flush(300);
-                    }
-                }
-            }
-        }
-        //If status is ok and whe have dirs created, returns counter to inform
-        if ($status and $counter) {
-            return $counter;
-        } else {
-            return $status;
-        }
-    }
-
-
-    //This function creates all the structures for every module in backup file
-    //Depending what has been selected.
-    function restore_create_modules($restore,$xml_file) {
-        global $CFG;
-
-        $status = true;
-        //Check it exists
-        if (!file_exists($xml_file)) {
-            $status = false;
-        }
-        //Get info from xml
-        if ($status) {
-            //info will contain the id and modtype of every module
-            //in backup_ids->info will be the real info (serialized)
-            $info = restore_read_xml_modules($restore,$xml_file);
-        }
-        //Now, if we have anything in info, we have to restore that mods
-        //from backup_ids (calling every mod restore function)
-        if ($info) {
-            if ($info !== true) {
-                if (!defined('RESTORE_SILENTLY')) {
-                    echo '<ul>';
-                }
-                //Iterate over each module
-                foreach ($info as $mod) {
-                    if (empty($restore->mods[$mod->modtype]->granular)  // We don't care about per instance, i.e. restore all instances.
-                        || (array_key_exists($mod->id,$restore->mods[$mod->modtype]->instances)
-                            && !empty($restore->mods[$mod->modtype]->instances[$mod->id]->restore))) {
-                        $modrestore = $mod->modtype."_restore_mods";
-                        if (function_exists($modrestore)) {                                               //Debug
-                             // we want to restore all mods even when one fails
-                             // incorrect code here ignored any errors during module restore in 1.6-1.8
-                            $status = $status && $modrestore($mod,$restore);
-                        } else {
-                            //Something was wrong. Function should exist.
-                            $status = false;
-                        }
-                    }
-                }
-                if (!defined('RESTORE_SILENTLY')) {
-                    echo '</ul>';
-                }
-            }
-        } else {
-            $status = false;
-        }
-       return $status;
-    }
-
-    //This function creates all the structures for every log in backup file
-    //Depending what has been selected.
-    function restore_create_logs($restore,$xml_file) {
-        global $CFG, $DB;
-
-        //Number of records to get in every chunk
-        $recordset_size = 4;
-        //Counter, points to current record
-        $counter = 0;
-        //To count all the recods to restore
-        $count_logs = 0;
-
-        $status = true;
-        //Check it exists
-        if (!file_exists($xml_file)) {
-            $status = false;
-        }
-        //Get info from xml
-        if ($status) {
-            //count_logs will contain the number of logs entries to process
-            //in backup_ids->info will be the real info (serialized)
-            $count_logs = restore_read_xml_logs($restore,$xml_file);
-        }
-
-        //Now, if we have records in count_logs, we have to restore that logs
-        //from backup_ids. This piece of code makes calls to:
-        // - restore_log_course() if it's a course log
-        // - restore_log_user() if it's a user log
-        // - restore_log_module() if it's a module log.
-        //And all is segmented in chunks to allow large recordsets to be restored !!
-        if ($count_logs > 0) {
-            while ($counter < $count_logs) {
-                //Get a chunk of records
-                //Take old_id twice to avoid adodb limitation
-                $logs = $DB->get_records("backup_ids", array("table_name"=>'log', 'backup_code'=>$restore->backup_unique_code),"old_id","old_id",$counter,$recordset_size);
-                //We have logs
-                if ($logs) {
-                    //Iterate
-                    foreach ($logs as $log) {
-                        //Get the full record from backup_ids
-                        $data = backup_getid($restore->backup_unique_code,"log",$log->old_id);
-                        if ($data) {
-                            //Now get completed xmlized object
-                            $info = $data->info;
-                            //traverse_xmlize($info);                                                                     //Debug
-                            //print_object ($GLOBALS['traverse_array']);                                                  //Debug
-                            //$GLOBALS['traverse_array']="";                                                              //Debug
-                            //Now build the LOG record structure
-                            $dblog = new object();
-                            $dblog->time = backup_todb($info['LOG']['#']['TIME']['0']['#']);
-                            $dblog->userid = backup_todb($info['LOG']['#']['USERID']['0']['#']);
-                            $dblog->ip = backup_todb($info['LOG']['#']['IP']['0']['#']);
-                            $dblog->course = $restore->course_id;
-                            $dblog->module = backup_todb($info['LOG']['#']['MODULE']['0']['#']);
-                            $dblog->cmid = backup_todb($info['LOG']['#']['CMID']['0']['#']);
-                            $dblog->action = backup_todb($info['LOG']['#']['ACTION']['0']['#']);
-                            $dblog->url = backup_todb($info['LOG']['#']['URL']['0']['#']);
-                            $dblog->info = backup_todb($info['LOG']['#']['INFO']['0']['#']);
-                            //We have to recode the userid field
-                            $user = backup_getid($restore->backup_unique_code,"user",$dblog->userid);
-                            if ($user) {
-                                //echo "User ".$dblog->userid." to user ".$user->new_id."<br />";                             //Debug
-                                $dblog->userid = $user->new_id;
-                            }
-                            //We have to recode the cmid field (if module isn't "course" or "user")
-                            if ($dblog->module != "course" and $dblog->module != "user") {
-                                $cm = backup_getid($restore->backup_unique_code,"course_modules",$dblog->cmid);
-                                if ($cm) {
-                                    //echo "Module ".$dblog->cmid." to module ".$cm->new_id."<br />";                         //Debug
-                                    $dblog->cmid = $cm->new_id;
-                                } else {
-                                    $dblog->cmid = 0;
-                                }
-                            }
-                            //print_object ($dblog);                                                                        //Debug
-                            //Now, we redirect to the needed function to make all the work
-                            if ($dblog->module == "course") {
-                                //It's a course log,
-                                $stat = restore_log_course($restore,$dblog);
-                            } elseif ($dblog->module == "user") {
-                                //It's a user log,
-                                $stat = restore_log_user($restore,$dblog);
-                            } else {
-                                //It's a module log,
-                                $stat = restore_log_module($restore,$dblog);
-                            }
-                        }
-
-                        //Do some output
-                        $counter++;
-                        if ($counter % 10 == 0) {
-                            if (!defined('RESTORE_SILENTLY')) {
-                                echo ".";
-                                if ($counter % 200 == 0) {
-                                    echo "<br />";
-                                }
-                            }
-                            backup_flush(300);
-                        }
-                    }
-                } else {
-                    //We never should arrive here
-                    $counter = $count_logs;
-                    $status = false;
-                }
-            }
-        }
-
-        return $status;
-    }
-
-    //This function inserts a course log record, calculating the URL field as necessary
-    function restore_log_course($restore,$log) {
-        global $DB;
-
-        $status = true;
-        $toinsert = false;
-
-        //echo "<hr />Before transformations<br />";                                        //Debug
-        //print_object($log);                                                           //Debug
-        //Depending of the action, we recode different things
-        switch ($log->action) {
-        case "view":
-            $log->url = "view.php?id=".$log->course;
-            $log->info = $log->course;
-            $toinsert = true;
-            break;
-        case "guest":
-            $log->url = "view.php?id=".$log->course;
-            $toinsert = true;
-            break;
-        case "user report":
-            //recode the info field (it's the user id)
-            $user = backup_getid($restore->backup_unique_code,"user",$log->info);
-            if ($user) {
-                $log->info = $user->new_id;
-                //Now, extract the mode from the url field
-                $mode = substr(strrchr($log->url,"="),1);
-                $log->url = "user.php?id=".$log->course."&user=".$log->info."&mode=".$mode;
-                $toinsert = true;
-            }
-            break;
-        case "add mod":
-            //Extract the course_module from the url field
-            $cmid = substr(strrchr($log->url,"="),1);
-            //recode the course_module to see it it has been restored
-            $cm = backup_getid($restore->backup_unique_code,"course_modules",$cmid);
-            if ($cm) {
-                $cmid = $cm->new_id;
-                //Extract the module name and the module id from the info field
-                $modname = strtok($log->info," ");
-                $modid = strtok(" ");
-                //recode the module id to see if it has been restored
-                $mod = backup_getid($restore->backup_unique_code,$modname,$modid);
-                if ($mod) {
-                    $modid = $mod->new_id;
-                    //Now I have everything so reconstruct url and info
-                    $log->info = $modname." ".$modid;
-                    $log->url = "../mod/".$modname."/view.php?id=".$cmid;
-                    $toinsert = true;
-                }
-            }
-            break;
-        case "update mod":
-            //Extract the course_module from the url field
-            $cmid = substr(strrchr($log->url,"="),1);
-            //recode the course_module to see it it has been restored
-            $cm = backup_getid($restore->backup_unique_code,"course_modules",$cmid);
-            if ($cm) {
-                $cmid = $cm->new_id;
-                //Extract the module name and the module id from the info field
-                $modname = strtok($log->info," ");
-                $modid = strtok(" ");
-                //recode the module id to see if it has been restored
-                $mod = backup_getid($restore->backup_unique_code,$modname,$modid);
-                if ($mod) {
-                    $modid = $mod->new_id;
-                    //Now I have everything so reconstruct url and info
-                    $log->info = $modname." ".$modid;
-                    $log->url = "../mod/".$modname."/view.php?id=".$cmid;
-                    $toinsert = true;
-                }
-            }
-            break;
-        case "delete mod":
-            $log->url = "view.php?id=".$log->course;
-            $toinsert = true;
-            break;
-        case "update":
-            $log->url = "edit.php?id=".$log->course;
-            $log->info = "";
-            $toinsert = true;
-            break;
-        case "unenrol":
-            //recode the info field (it's the user id)
-            $user = backup_getid($restore->backup_unique_code,"user",$log->info);
-            if ($user) {
-                $log->info = $user->new_id;
-                $log->url = "view.php?id=".$log->course;
-                $toinsert = true;
-            }
-            break;
-        case "enrol":
-            //recode the info field (it's the user id)
-            $user = backup_getid($restore->backup_unique_code,"user",$log->info);
-            if ($user) {
-                $log->info = $user->new_id;
-                $log->url = "view.php?id=".$log->course;
-                $toinsert = true;
-            }
-            break;
-        case "editsection":
-            //Extract the course_section from the url field
-            $secid = substr(strrchr($log->url,"="),1);
-            //recode the course_section to see if it has been restored
-            $sec = backup_getid($restore->backup_unique_code,"course_sections",$secid);
-            if ($sec) {
-                $secid = $sec->new_id;
-                //Now I have everything so reconstruct url and info
-                $log->url = "editsection.php?id=".$secid;
-                $toinsert = true;
-            }
-            break;
-        case "new":
-            $log->url = "view.php?id=".$log->course;
-            $log->info = "";
-            $toinsert = true;
-            break;
-        case "recent":
-            $log->url = "recent.php?id=".$log->course;
-            $log->info = "";
-            $toinsert = true;
-            break;
-        case "report log":
-            $log->url = "report/log/index.php?id=".$log->course;
-            $log->info = $log->course;
-            $toinsert = true;
-            break;
-        case "report live":
-            $log->url = "report/log/live.php?id=".$log->course;
-            $log->info = $log->course;
-            $toinsert = true;
-            break;
-        case "report outline":
-            $log->url = "report/outline/index.php?id=".$log->course;
-            $log->info = $log->course;
-            $toinsert = true;
-            break;
-        case "report participation":
-            $log->url = "report/participation/index.php?id=".$log->course;
-            $log->info = $log->course;
-            $toinsert = true;
-            break;
-        case "report stats":
-            $log->url = "report/stats/index.php?id=".$log->course;
-            $log->info = $log->course;
-            $toinsert = true;
-            break;
-        default:
-            echo "action (".$log->module."-".$log->action.") unknown. Not restored<br />";                 //Debug
-            break;
-        }
-
-        //echo "After transformations<br />";                                             //Debug
-        //print_object($log);                                                           //Debug
-
-        //Now if $toinsert is set, insert the record
-        if ($toinsert) {
-            //echo "Inserting record<br />";                                              //Debug
-            $status = $DB->insert_record("log",$log);
-        }
-        return $status;
-    }
-
-    //This function inserts a user log record, calculating the URL field as necessary
-    function restore_log_user($restore,$log) {
-        global $DB;
-
-        $status = true;
-        $toinsert = false;
-
-        //echo "<hr />Before transformations<br />";                                        //Debug
-        //print_object($log);                                                           //Debug
-        //Depending of the action, we recode different things
-        switch ($log->action) {
-        case "view":
-            //recode the info field (it's the user id)
-            $user = backup_getid($restore->backup_unique_code,"user",$log->info);
-            if ($user) {
-                $log->info = $user->new_id;
-                $log->url = "view.php?id=".$log->info."&course=".$log->course;
-                $toinsert = true;
-            }
-            break;
-        case "change password":
-            //recode the info field (it's the user id)
-            $user = backup_getid($restore->backup_unique_code,"user",$log->info);
-            if ($user) {
-                $log->info = $user->new_id;
-                $log->url = "view.php?id=".$log->info."&course=".$log->course;
-                $toinsert = true;
-            }
-            break;
-        case "login":
-            //recode the info field (it's the user id)
-            $user = backup_getid($restore->backup_unique_code,"user",$log->info);
-            if ($user) {
-                $log->info = $user->new_id;
-                $log->url = "view.php?id=".$log->info."&course=".$log->course;
-                $toinsert = true;
-            }
-            break;
-        case "logout":
-            //recode the info field (it's the user id)
-            $user = backup_getid($restore->backup_unique_code,"user",$log->info);
-            if ($user) {
-                $log->info = $user->new_id;
-                $log->url = "view.php?id=".$log->info."&course=".$log->course;
-                $toinsert = true;
-            }
-            break;
-        case "view all":
-            $log->url = "view.php?id=".$log->course;
-            $log->info = "";
-            $toinsert = true;
-        case "update":
-            //We split the url by ampersand char
-            $first_part = strtok($log->url,"&");
-            //Get data after the = char. It's the user being updated
-            $userid = substr(strrchr($first_part,"="),1);
-            //Recode the user
-            $user = backup_getid($restore->backup_unique_code,"user",$userid);
-            if ($user) {
-                $log->info = "";
-                $log->url = "view.php?id=".$user->new_id."&course=".$log->course;
-                $toinsert = true;
-            }
-            break;
-        default:
-            echo "action (".$log->module."-".$log->action.") unknown. Not restored<br />";                 //Debug
-            break;
-        }
-
-        //echo "After transformations<br />";                                             //Debug
-        //print_object($log);                                                           //Debug
-
-        //Now if $toinsert is set, insert the record
-        if ($toinsert) {
-            //echo "Inserting record<br />";                                              //Debug
-            $status = $DB->insert_record("log",$log);
-        }
-        return $status;
-    }
-
-    //This function inserts a module log record, calculating the URL field as necessary
-    function restore_log_module($restore,$log) {
-        global $DB;
-
-        $status = true;
-        $toinsert = false;
-
-        //echo "<hr />Before transformations<br />";                                        //Debug
-        //print_object($log);                                                           //Debug
-
-        //Now we see if the required function in the module exists
-        $function = $log->module."_restore_logs";
-        if (function_exists($function)) {
-            //Call the function
-            $log = $function($restore,$log);
-            //If everything is ok, mark the insert flag
-            if ($log) {
-                $toinsert = true;
-            }
-        }
-
-        //echo "After transformations<br />";                                             //Debug
-        //print_object($log);                                                           //Debug
-
-        //Now if $toinsert is set, insert the record
-        if ($toinsert) {
-            //echo "Inserting record<br />";                                              //Debug
-            $status = $DB->insert_record("log",$log);
-        }
-        return $status;
-    }
-
-    //This function adjusts the instance field into course_modules. It's executed after
-    //modules restore. There, we KNOW the new instance id !!
-    function restore_check_instances($restore) {
-        global $CFG, $DB;
-
-        $status = true;
-
-        //We are going to iterate over each course_module saved in backup_ids
-        $course_modules = $DB->get_records_sql("SELECT old_id,new_id
-                                                  FROM {backup_ids}
-                                                 WHERE backup_code = ? AND
-                                                       table_name = 'course_modules'", array($restore->backup_unique_code));
-        if ($course_modules) {
-            foreach($course_modules as $cm) {
-                //Get full record, using backup_getids
-                $cm_module = backup_getid($restore->backup_unique_code,"course_modules",$cm->old_id);
-                //Now we are going to the REAL course_modules to get its type (field module)
-                $module = $DB->get_record("course_modules", array("id"=>$cm_module->new_id));
-                if ($module) {
-                    //We know the module type id. Get the name from modules
-                    $type = $DB->get_record("modules", array("id"=>$module->module));
-                    if ($type) {
-                        //We know the type name and the old_id. Get its new_id
-                        //from backup_ids. It's the instance !!!
-                        $instance =  backup_getid($restore->backup_unique_code,$type->name,$cm_module->info);
-                        if ($instance) {
-                            //We have the new instance, so update the record in course_modules
-                            $module->instance = $instance->new_id;
-                            //print_object ($module);                             //Debug
-                            $status = $DB->update_record("course_modules",$module);
-                        } else {
-                            $status = false;
-                        }
-                    } else {
-                        $status = false;
-                    }
-                } else {
-                    $status = false;
-               }
-               // MDL-14326 remove empty course modules instance's (credit goes to John T. Macklin from Remote Learner)
-               $course_modules_inst_zero = $DB->get_records_sql(
-                                        "SELECT id, course, instance
-                                           FROM {course_modules}
-                                          WHERE id = ? AND instance = 0", array($cm_module->new_id));
-
-                    if($course_modules_inst_zero){ // Clean up the invalid instances
-                         foreach($course_modules_inst_zero as $course_modules_inst){
-                             $DB->delete_records('course_modules', array('id'=>$course_modules_inst->id));
-                         }
-                    }
-
-            }
-        /// Finally, calculate modinfo cache.
-            rebuild_course_cache($restore->course_id);
-        }
-
-
-        return $status;
-    }
-
-    //=====================================================================================
-    //==                                                                                 ==
-    //==                         XML Functions (SAX)                                     ==
-    //==                                                                                 ==
-    //=====================================================================================
-
-    /// This is the class used to split, in first instance, the monolithic moodle.xml into
-    /// smaller xml files allowing the MoodleParser later to process only the required info
-    /// based in each $todo, instead of processing the whole xml for each $todo. In theory
-    /// processing time can be reduced upto 1/20th of original time (depending of the
-    /// number of $todo in the original moodle.xml file)
-    ///
-    /// Anyway, note it's a general splitter parser, and only needs to be instantiated
-    /// with the proper destination dir and the tosplit configuration. Be careful when
-    /// using it because it doesn't support XML attributes nor real cdata out from tags.
-    /// (both not used in the target Moodle backup files)
-
-    class moodle_splitter_parser {
-        var $level = 0;            /// Level we are
-        var $tree = array();       /// Array of levels we are
-        var $cdata = '';           /// Raw storage for character data
-        var $content = '';         /// Content buffer to be printed to file
-        var $trailing= '';         /// Content of the trailing tree for each splited file
-        var $savepath = null;      /// Path to store splited files
-        var $fhandler = null;      /// Current file we are writing to
-        var $tosplit = array();    /// Array defining the files we want to split, in this format:
-                                   /// array( level/tag/level/tag => filename)
-        var $splitwords = array(); /// Denormalised array containing the potential tags
-                                   /// being a split point. To speed up check_split_point()
-        var $maxsplitlevel = 0;    /// Precalculated max level where any split happens. To speed up check_split_point()
-        var $buffersize = 65536;   /// 64KB is a good write buffer. Don't expect big benefits by increasing this.
-        var $repectformat = false; /// With this setting enabled, the splited files will look like the original one
-                                   /// with all the indentations 100% copied from original (character data outer tags).
-                                   /// But this is a waste of time from our perspective, and splited xml files are completely
-                                   /// functional without that, so we disable this for production, generating a more compact
-                                   /// XML quicker
-
-    /// PHP4 constructor
-        function moodle_splitter_parser($savepath, $tosplit = null) {
-            return $this->__construct($savepath, $tosplit);
-        }
-
-    /// PHP5 constructor
-        function __construct($savepath, $tosplit = null) {
-            $this->savepath = $savepath;
-            if (!empty($tosplit)) {
-                $this->tosplit = $tosplit;
-            } else { /// No tosplit list passed, process all the possible parts in one moodle.xml file
-                $this->tosplit = array(
-                                     '1/MOODLE_BACKUP/2/INFO'        => 'split_info.xml',
-                                     '1/MOODLE_BACKUP/2/ROLES'       => 'split_roles.xml',
-                                     '2/COURSE/3/HEADER'             => 'split_course_header.xml',
-                                     '2/COURSE/3/BLOCKS'             => 'split_blocks.xml',
-                                     '2/COURSE/3/SECTIONS'           => 'split_sections.xml',
-                                     '2/COURSE/3/FORMATDATA'         => 'split_formatdata.xml',
-                                     '2/COURSE/3/METACOURSE'         => 'split_metacourse.xml',
-                                     '2/COURSE/3/GRADEBOOK'          => 'split_gradebook.xml',
-                                     '2/COURSE/3/USERS'              => 'split_users.xml',
-                                     '2/COURSE/3/MESSAGES'           => 'split_messages.xml',
-                                     '2/COURSE/3/BLOGS'              => 'split_blogs.xml',
-                                     '2/COURSE/3/QUESTION_CATEGORIES'=> 'split_questions.xml',
-                                     '2/COURSE/3/SCALES'             => 'split_scales.xml',
-                                     '2/COURSE/3/GROUPS'             => 'split_groups.xml',
-                                     '2/COURSE/3/GROUPINGS'          => 'split_groupings.xml',
-                                     '2/COURSE/3/GROUPINGSGROUPS'    => 'split_groupingsgroups.xml',
-                                     '2/COURSE/3/EVENTS'             => 'split_events.xml',
-                                     '2/COURSE/3/MODULES'            => 'split_modules.xml',
-                                     '2/COURSE/3/LOGS'               => 'split_logs.xml'
-                                 );
-            }
-        /// Precalculate some info used to speedup checks
-            foreach ($this->tosplit as $key=>$value) {
-                $this->splitwords[basename($key)] = true;
-                if (((int) basename(dirname($key))) > $this->maxsplitlevel) {
-                    $this->maxsplitlevel = (int) basename(dirname($key));
-                }
-            }
-        }
-
-        /// Given one tag being opened, check if it's one split point.
-        /// Return false or split filename
-        function check_split_point($tag) {
-        /// Quick check. Level < 2 cannot be a split point
-            if ($this->level < 2) {
-                return false;
-            }
-        /// Quick check. Current tag against potential splitwords
-            if (!isset($this->splitwords[$tag])) {
-                return false;
-            }
-        /// Prev test passed, take a look to 2-level tosplit
-            $keytocheck = ($this->level - 1) . '/' . $this->tree[$this->level - 1] . '/' . $this->level . '/' . $this->tree[$this->level];
-            if (!isset($this->tosplit[$keytocheck])) {
-                return false;
-            }
-        /// Prev test passed, we are in a split point, return new filename
-            return $this->tosplit[$keytocheck];
-        }
-
-        /// To append data (xml-escaped) to contents buffer
-        function character_data($parser, $data) {
-
-            ///$this->content .= preg_replace($this->entity_find, $this->entity_replace, $data); ///40% slower
-            ///$this->content .= str_replace($this->entity_find, $this->entity_replace, $data);  ///25% slower
-            ///$this->content .= htmlspecialchars($data);                                        ///the best
-            /// Instead of htmlspecialchars() each chunk of character data, we are going to
-            /// concat it without transformation and will apply the htmlspecialchars() when
-            /// that character data is, efectively, going to be added to contents buffer. This
-            /// makes the number of transformations to be reduced (speedup) and avoid potential
-            /// problems with transformations being applied "in the middle" of multibyte chars.
-            $this->cdata .= $data;
-        }
-
-        /// To detect start of tags, keeping level, tree and fhandle updated.
-        /// Also handles creation of split files
-        function start_tag($parser, $tag, $attrs) {
-
-        /// Update things before processing
-            $this->level++;
-            $this->tree[$this->level] = $tag;
-
-        /// Check if we need to start a new split file,
-        /// Speedup: we only do that if we haven't a fhandler and if level <= $maxsplitlevel
-            if ($this->level <= $this->maxsplitlevel && !$this->fhandler && $newfilename = $this->check_split_point($tag)) {
-            /// Open new file handler, init everything
-                $this->fhandler = fopen($this->savepath . '/' . $newfilename, 'w');
-                $this->content = '';
-                $this->cdata = '';
-                $this->trailing = '';
-            /// Build the original leading tree (and calculate the original trailing one)
-                for ($l = 1; $l < $this->level; $l++) {
-                    $this->content .= "<{$this->tree[$l]}>\n";
-                    $this->trailing = "\n</{$this->tree[$l]}>" . $this->trailing;
-                }
-            }
-        /// Perform xml-entities transformation and add to contents buffer together with opening tag.
-        /// Speedup. We lose nice formatting of the split XML but avoid 50% of transformations and XML is 100% equivalent
-            $this->content .= ($this->repectformat ? htmlspecialchars($this->cdata) : '') . "<$tag>";
-            $this->cdata = '';
-        }
-
-        /// To detect end of tags, keeping level, tree and fhandle updated, writting contents buffer to split file.
-        /// Also handles closing of split files
-        function end_tag($parser, $tag) {
-
-        /// Perform xml-entities transformation and add to contents buffer together with closing tag, repecting (or no) format
-            $this->content .= ($this->repectformat ? htmlspecialchars($this->cdata) : htmlspecialchars(trim($this->cdata))) . "</$tag>";
-            $this->cdata = '';
-
-        /// Check if we need to close current split file
-        /// Speedup: we only do that if we have a fhandler and if level <= $maxsplitlevel
-            if ($this->level <= $this->maxsplitlevel && $this->fhandler && $newfilename = $this->check_split_point($tag)) {
-            /// Write pending contents buffer before closing. It's a must
-                fwrite($this->fhandler, $this->content);
-                $this->content = "";
-            /// Write the original trailing tree for fhandler
-                fwrite($this->fhandler, $this->trailing);
-                fclose($this->fhandler);
-                $this->fhandler = null;
-            } else {
-            /// Normal write of contents (use one buffer to improve speed)
-                if ($this->fhandler && strlen($this->content) > $this->buffersize) {
-                    fwrite($this->fhandler, $this->content);
-                    $this->content = "";
-                }
-            }
-
-        /// Update things after processing
-            $this->tree[$this->level] = "";
-            $this->level--;
-
-        }
-    }
-
-    /// This function executes the moodle_splitter_parser, causing the monolithic moodle.xml
-    /// file to be splitted in n smaller files for better treatament by the MoodleParser in restore_read_xml()
-    function restore_split_xml ($xml_file, $preferences) {
-
-        $status = true;
-
-        $xml_parser = xml_parser_create('UTF-8');
-        $split_parser = new moodle_splitter_parser(dirname($xml_file));
-        xml_set_object($xml_parser,$split_parser);
-        xml_set_element_handler($xml_parser, 'start_tag', 'end_tag');
-        xml_set_character_data_handler($xml_parser, 'character_data');
-
-        $doteach = filesize($xml_file) / 20;
-        $fromdot = 0;
-
-        $fp = fopen($xml_file,"r")
-            or $status = false;
-        if ($status) {
-            $lasttime = time();
-            while ($data = fread($fp, 8192)) {
-                if (!defined('RESTORE_SILENTLY')) {
-                    $fromdot += 8192;
-                    if ($fromdot > $doteach) {
-                        echo ".";
-                        backup_flush(300);
-                        $fromdot = 0;
-                    }
-                    if ((time() - $lasttime) > 10) {
-                        $lasttime = time();
-                        backup_flush(300);
-                    }
-                }
-                xml_parse($xml_parser, $data, feof($fp))
-                    or die(sprintf("XML error: %s at line %d",
-                                   xml_error_string(xml_get_error_code($xml_parser)),
-                                   xml_get_current_line_number($xml_parser)));
-            }
-            fclose($fp);
-        }
-        xml_parser_free($xml_parser);
-        return $status;
-    }
-
-    //This is the class used to do all the xml parse
-    class MoodleParser {
-
-        var $level = 0;        //Level we are
-        var $counter = 0;      //Counter
-        var $tree = array();   //Array of levels we are
-        var $content = "";     //Content under current level
-        var $todo = "";        //What we hav to do when parsing
-        var $info = "";        //Information collected. Temp storage. Used to return data after parsing.
-        var $temp = "";        //Temp storage.
-        var $preferences = ""; //Preferences about what to load !!
-        var $finished = false; //Flag to say xml_parse to stop
-
-        //This function is used to get the current contents property value
-        //They are trimed (and converted from utf8 if needed)
-        function getContents() {
-            return trim($this->content);
-        }
-
-        //This is the startTag handler we use where we are reading the info zone ($todo="INFO")
-        function startElementInfo($parser, $tagName, $attrs) {
-            //Refresh properties
-            $this->level++;
-            $this->tree[$this->level] = $tagName;
-
-            //Output something to avoid browser timeouts...
-            //backup_flush();
-
-            //Check if we are into INFO zone
-            //if ($this->tree[2] == "INFO")                                                             //Debug
-            //    echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;".$tagName."&gt;<br />\n";   //Debug
-        }
-
-                //This is the startTag handler we use where we are reading the info zone ($todo="INFO")
-        function startElementRoles($parser, $tagName, $attrs) {
-            //Refresh properties
-            $this->level++;
-            $this->tree[$this->level] = $tagName;
-
-            //Output something to avoid browser timeouts...
-            //backup_flush();
-
-            //Check if we are into INFO zone
-            //if ($this->tree[2] == "INFO")                                                             //Debug
-            //    echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;".$tagName."&gt;<br />\n";   //Debug
-        }
-
-
-        //This is the startTag handler we use where we are reading the course header zone ($todo="COURSE_HEADER")
-        function startElementCourseHeader($parser, $tagName, $attrs) {
-            //Refresh properties
-            $this->level++;
-            $this->tree[$this->level] = $tagName;
-
-            //Output something to avoid browser timeouts...
-            //backup_flush();
-
-            //Check if we are into COURSE_HEADER zone
-            //if ($this->tree[3] == "HEADER")                                                           //Debug
-            //    echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;".$tagName."&gt;<br />\n";   //Debug
-        }
-
-        //This is the startTag handler we use where we are reading the blocks zone ($todo="BLOCKS")
-        function startElementBlocks($parser, $tagName, $attrs) {
-            //Refresh properties
-            $this->level++;
-            $this->tree[$this->level] = $tagName;
-
-            //Output something to avoid browser timeouts...
-            //backup_flush();
-
-            //Check if we are into BLOCKS zone
-            //if ($this->tree[3] == "BLOCKS")                                                         //Debug
-            //    echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;".$tagName."&gt;<br />\n";   //Debug
-
-            //If we are under a BLOCK tag under a BLOCKS zone, accumule it
-            if (isset($this->tree[4]) and isset($this->tree[3])) {  //
-                if ($this->tree[4] == "BLOCK" and $this->tree[3] == "BLOCKS") {
-                    if (!isset($this->temp)) {
-                        $this->temp = "";
-                    }
-                    $this->temp .= "<".$tagName.">";
-                }
-            }
-        }
-
-        //This is the startTag handler we use where we are reading the sections zone ($todo="SECTIONS")
-        function startElementSections($parser, $tagName, $attrs) {
-            //Refresh properties
-            $this->level++;
-            $this->tree[$this->level] = $tagName;
-
-            //Output something to avoid browser timeouts...
-            //backup_flush();
-
-            //Check if we are into SECTIONS zone
-            //if ($this->tree[3] == "SECTIONS")                                                         //Debug
-            //    echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;".$tagName."&gt;<br />\n";   //Debug
-        }
-
-        //This is the startTag handler we use where we are reading the optional format data zone ($todo="FORMATDATA")
-        function startElementFormatData($parser, $tagName, $attrs) {
-            //Refresh properties
-            $this->level++;
-            $this->tree[$this->level] = $tagName;
-
-            //Output something to avoid browser timeouts...
-            //backup_flush();
-
-            //Accumulate all the data inside this tag
-            if (isset($this->tree[3]) && $this->tree[3] == "FORMATDATA") {
-                if (!isset($this->temp)) {
-                    $this->temp = '';
-                }
-                $this->temp .= "<".$tagName.">";
-            }
-
-            //Check if we are into FORMATDATA zone
-            //if ($this->tree[3] == "FORMATDATA")                                                         //Debug
-            //    echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;".$tagName."&gt;<br />\n";   //Debug
-        }
-
-        //This is the startTag handler we use where we are reading the metacourse zone ($todo="METACOURSE")
-        function startElementMetacourse($parser, $tagName, $attrs) {
-
-            //Refresh properties
-            $this->level++;
-            $this->tree[$this->level] = $tagName;
-
-            //Output something to avoid browser timeouts...
-            //backup_flush();
-
-            //Check if we are into METACOURSE zone
-            //if ($this->tree[3] == "METACOURSE")                                                         //Debug
-            //    echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;".$tagName."&gt;<br />\n";   //Debug
-        }
-
-        //This is the startTag handler we use where we are reading the gradebook zone ($todo="GRADEBOOK")
-        function startElementGradebook($parser, $tagName, $attrs) {
-
-            //Refresh properties
-            $this->level++;
-            $this->tree[$this->level] = $tagName;
-
-            //Output something to avoid browser timeouts...
-            //backup_flush();
-
-            //Check if we are into GRADEBOOK zone
-            //if ($this->tree[3] == "GRADEBOOK")                                                         //Debug
-            //    echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;".$tagName."&gt;<br />\n";  //Debug
-
-            //If we are under a GRADE_PREFERENCE, GRADE_LETTER or GRADE_CATEGORY tag under a GRADEBOOK zone, accumule it
-            if (isset($this->tree[5]) and isset($this->tree[3])) {
-                if (($this->tree[5] == "GRADE_ITEM" || $this->tree[5] == "GRADE_CATEGORY" || $this->tree[5] == "GRADE_LETTER" || $this->tree[5] == "GRADE_OUTCOME" || $this->tree[5] == "GRADE_OUTCOMES_COURSE" || $this->tree[5] == "GRADE_CATEGORIES_HISTORY" || $this->tree[5] == "GRADE_GRADES_HISTORY" || $this->tree[5] == "GRADE_TEXT_HISTORY" || $this->tree[5] == "GRADE_ITEM_HISTORY" || $this->tree[5] == "GRADE_OUTCOME_HISTORY") && ($this->tree[3] == "GRADEBOOK")) {
-
-                    if (!isset($this->temp)) {
-                        $this->temp = "";
-                    }
-                    $this->temp .= "<".$tagName.">";
-                }
-            }
-        }
-
-        //This is the startTag handler we use where we are reading the gradebook zone ($todo="GRADEBOOK")
-        function startElementOldGradebook($parser, $tagName, $attrs) {
-
-            //Refresh properties
-            $this->level++;
-            $this->tree[$this->level] = $tagName;
-
-            //Output something to avoid browser timeouts...
-            //backup_flush();
-
-            //Check if we are into GRADEBOOK zone
-            //if ($this->tree[3] == "GRADEBOOK")                                                         //Debug
-            //    echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;".$tagName."&gt;<br />\n";  //Debug
-
-            //If we are under a GRADE_PREFERENCE, GRADE_LETTER or GRADE_CATEGORY tag under a GRADEBOOK zone, accumule it
-            if (isset($this->tree[5]) and isset($this->tree[3])) {
-                if (($this->tree[5] == "GRADE_PREFERENCE" || $this->tree[5] == "GRADE_LETTER" || $this->tree[5] == "GRADE_CATEGORY" ) && ($this->tree[3] == "GRADEBOOK")) {
-                    if (!isset($this->temp)) {
-                        $this->temp = "";
-                    }
-                    $this->temp .= "<".$tagName.">";
-                }
-            }
-        }
-
-
-        //This is the startTag handler we use where we are reading the user zone ($todo="USERS")
-        function startElementUsers($parser, $tagName, $attrs) {
-            //Refresh properties
-            $this->level++;
-            $this->tree[$this->level] = $tagName;
-
-            //Check if we are into USERS zone
-            //if ($this->tree[3] == "USERS")                                                            //Debug
-            //    echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;".$tagName."&gt;<br />\n";   //Debug
-        }
-
-        //This is the startTag handler we use where we are reading the messages zone ($todo="MESSAGES")
-        function startElementMessages($parser, $tagName, $attrs) {
-            //Refresh properties
-            $this->level++;
-            $this->tree[$this->level] = $tagName;
-
-            //Output something to avoid browser timeouts...
-            //backup_flush();
-
-            //Check if we are into MESSAGES zone
-            //if ($this->tree[3] == "MESSAGES")                                                          //Debug
-            //    echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;".$tagName."&gt;<br />\n";  //Debug
-
-            //If we are under a MESSAGE tag under a MESSAGES zone, accumule it
-            if (isset($this->tree[4]) and isset($this->tree[3])) {
-                if (($this->tree[4] == "MESSAGE" || (isset($this->tree[5]) && $this->tree[5] == "CONTACT" )) and ($this->tree[3] == "MESSAGES")) {
-                    if (!isset($this->temp)) {
-                        $this->temp = "";
-                    }
-                    $this->temp .= "<".$tagName.">";
-                }
-            }
-        }
-
-        //This is the startTag handler we use where we are reading the blogs zone ($todo="BLOGS")
-        function startElementBlogs($parser, $tagName, $attrs) {
-            //Refresh properties
-            $this->level++;
-            $this->tree[$this->level] = $tagName;
-
-            //Output something to avoid browser timeouts...
-            //backup_flush();
-
-            //Check if we are into BLOGS zone
-            //if ($this->tree[3] == "BLOGS")                                                          //Debug
-            //    echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;".$tagName."&gt;<br />\n";  //Debug
-
-            //If we are under a BLOG tag under a BLOGS zone, accumule it
-            if (isset($this->tree[4]) and isset($this->tree[3])) {
-                if ($this->tree[4] == "BLOG" and $this->tree[3] == "BLOGS") {
-                    if (!isset($this->temp)) {
-                        $this->temp = "";
-                    }
-                    $this->temp .= "<".$tagName.">";
-                }
-            }
-        }
-
-        //This is the startTag handler we use where we are reading the questions zone ($todo="QUESTIONS")
-        function startElementQuestions($parser, $tagName, $attrs) {
-            //Refresh properties
-            $this->level++;
-            $this->tree[$this->level] = $tagName;
-
-            //if ($tagName == "QUESTION_CATEGORY" && $this->tree[3] == "QUESTION_CATEGORIES") {        //Debug
-            //    echo "<P>QUESTION_CATEGORY: ".strftime ("%X",time()),"-";                            //Debug
-            //}                                                                                        //Debug
-
-            //Output something to avoid browser timeouts...
-            //backup_flush();
-
-            //Check if we are into QUESTION_CATEGORIES zone
-            //if ($this->tree[3] == "QUESTION_CATEGORIES")                                              //Debug
-            //    echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;".$tagName."&gt;<br />\n";   //Debug
-
-            //If we are under a QUESTION_CATEGORY tag under a QUESTION_CATEGORIES zone, accumule it
-            if (isset($this->tree[4]) and isset($this->tree[3])) {
-                if (($this->tree[4] == "QUESTION_CATEGORY") and ($this->tree[3] == "QUESTION_CATEGORIES")) {
-                    if (!isset($this->temp)) {
-                        $this->temp = "";
-                    }
-                    $this->temp .= "<".$tagName.">";
-                }
-            }
-        }
-
-        //This is the startTag handler we use where we are reading the scales zone ($todo="SCALES")
-        function startElementScales($parser, $tagName, $attrs) {
-            //Refresh properties
-            $this->level++;
-            $this->tree[$this->level] = $tagName;
-
-            //if ($tagName == "SCALE" && $this->tree[3] == "SCALES") {                                 //Debug
-            //    echo "<P>SCALE: ".strftime ("%X",time()),"-";                                        //Debug
-            //}                                                                                        //Debug
-
-            //Output something to avoid browser timeouts...
-            //backup_flush();
-
-            //Check if we are into SCALES zone
-            //if ($this->tree[3] == "SCALES")                                                           //Debug
-            //    echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;".$tagName."&gt;<br />\n";   //Debug
-
-            //If we are under a SCALE tag under a SCALES zone, accumule it
-            if (isset($this->tree[4]) and isset($this->tree[3])) {
-                if (($this->tree[4] == "SCALE") and ($this->tree[3] == "SCALES")) {
-                    if (!isset($this->temp)) {
-                        $this->temp = "";
-                    }
-                    $this->temp .= "<".$tagName.">";
-                }
-            }
-        }
-
-        function startElementGroups($parser, $tagName, $attrs) {
-            //Refresh properties
-            $this->level++;
-            $this->tree[$this->level] = $tagName;
-
-            //if ($tagName == "GROUP" && $this->tree[3] == "GROUPS") {                                 //Debug
-            //    echo "<P>GROUP: ".strftime ("%X",time()),"-";                                        //Debug
-            //}                                                                                        //Debug
-
-            //Output something to avoid browser timeouts...
-            //backup_flush();
-
-            //Check if we are into GROUPS zone
-            //if ($this->tree[3] == "GROUPS")                                                           //Debug
-            //    echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;".$tagName."&gt;<br />\n";   //Debug
-
-            //If we are under a GROUP tag under a GROUPS zone, accumule it
-            if (isset($this->tree[4]) and isset($this->tree[3])) {
-                if (($this->tree[4] == "GROUP") and ($this->tree[3] == "GROUPS")) {
-                    if (!isset($this->temp)) {
-                        $this->temp = "";
-                    }
-                    $this->temp .= "<".$tagName.">";
-                }
-            }
-        }
-
-        function startElementGroupings($parser, $tagName, $attrs) {
-            //Refresh properties
-            $this->level++;
-            $this->tree[$this->level] = $tagName;
-
-            //if ($tagName == "GROUPING" && $this->tree[3] == "GROUPINGS") {                                 //Debug
-            //    echo "<P>GROUPING: ".strftime ("%X",time()),"-";                                        //Debug
-            //}                                                                                        //Debug
-
-            //Output something to avoid browser timeouts...
-            //backup_flush();
-
-            //Check if we are into GROUPINGS zone
-            //if ($this->tree[3] == "GROUPINGS")                                                           //Debug
-            //    echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;".$tagName."&gt;<br />\n";   //Debug
-
-            //If we are under a GROUPING tag under a GROUPINGS zone, accumule it
-            if (isset($this->tree[4]) and isset($this->tree[3])) {
-                if (($this->tree[4] == "GROUPING") and ($this->tree[3] == "GROUPINGS")) {
-                    if (!isset($this->temp)) {
-                        $this->temp = "";
-                    }
-                    $this->temp .= "<".$tagName.">";
-                }
-            }
-        }
-
-        function startElementGroupingsGroups($parser, $tagName, $attrs) {
-            //Refresh properties
-            $this->level++;
-            $this->tree[$this->level] = $tagName;
-
-            //if ($tagName == "GROUPINGGROUP" && $this->tree[3] == "GROUPINGSGROUPS") {                                 //Debug
-            //    echo "<P>GROUPINGSGROUP: ".strftime ("%X",time()),"-";                                        //Debug
-            //}                                                                                        //Debug
-
-            //Output something to avoid browser timeouts...
-            backup_flush();
-
-            //Check if we are into GROUPINGSGROUPS zone
-            //if ($this->tree[3] == "GROUPINGSGROUPS")                                                           //Debug
-            //    echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;".$tagName."&gt;<br />\n";   //Debug
-
-            //If we are under a GROUPINGGROUP tag under a GROUPINGSGROUPS zone, accumule it
-            if (isset($this->tree[4]) and isset($this->tree[3])) {
-                if (($this->tree[4] == "GROUPINGGROUP") and ($this->tree[3] == "GROUPINGSGROUPS")) {
-                    if (!isset($this->temp)) {
-                        $this->temp = "";
-                    }
-                    $this->temp .= "<".$tagName.">";
-                }
-            }
-        }
-
-        //This is the startTag handler we use where we are reading the events zone ($todo="EVENTS")
-        function startElementEvents($parser, $tagName, $attrs) {
-            //Refresh properties
-            $this->level++;
-            $this->tree[$this->level] = $tagName;
-
-            //if ($tagName == "EVENT" && $this->tree[3] == "EVENTS") {                                 //Debug
-            //    echo "<P>EVENT: ".strftime ("%X",time()),"-";                                        //Debug
-            //}                                                                                        //Debug
-
-            //Output something to avoid browser timeouts...
-            //backup_flush();
-
-            //Check if we are into EVENTS zone
-            //if ($this->tree[3] == "EVENTS")                                                           //Debug
-            //    echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;".$tagName."&gt;<br />\n";   //Debug
-
-            //If we are under a EVENT tag under a EVENTS zone, accumule it
-            if (isset($this->tree[4]) and isset($this->tree[3])) {
-                if (($this->tree[4] == "EVENT") and ($this->tree[3] == "EVENTS")) {
-                    if (!isset($this->temp)) {
-                        $this->temp = "";
-                    }
-                    $this->temp .= "<".$tagName.">";
-                }
-            }
-        }
-
-        //This is the startTag handler we use where we are reading the modules zone ($todo="MODULES")
-        function startElementModules($parser, $tagName, $attrs) {
-            //Refresh properties
-            $this->level++;
-            $this->tree[$this->level] = $tagName;
-
-            //if ($tagName == "MOD" && $this->tree[3] == "MODULES") {                                     //Debug
-            //    echo "<P>MOD: ".strftime ("%X",time()),"-";                                             //Debug
-            //}                                                                                           //Debug
-
-            //Output something to avoid browser timeouts...
-            //backup_flush();
-
-            //Check if we are into MODULES zone
-            //if ($this->tree[3] == "MODULES")                                                          //Debug
-            //    echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;".$tagName."&gt;<br />\n";   //Debug
-
-            //If we are under a MOD tag under a MODULES zone, accumule it
-            if (isset($this->tree[4]) and isset($this->tree[3])) {
-                if (($this->tree[4] == "MOD") and ($this->tree[3] == "MODULES")) {
-                    if (!isset($this->temp)) {
-                        $this->temp = "";
-                    }
-                    $this->temp .= "<".$tagName.">";
-                }
-            }
-        }
-
-        //This is the startTag handler we use where we are reading the logs zone ($todo="LOGS")
-        function startElementLogs($parser, $tagName, $attrs) {
-            //Refresh properties
-            $this->level++;
-            $this->tree[$this->level] = $tagName;
-
-            //if ($tagName == "LOG" && $this->tree[3] == "LOGS") {                                        //Debug
-            //    echo "<P>LOG: ".strftime ("%X",time()),"-";                                             //Debug
-            //}                                                                                           //Debug
-
-            //Output something to avoid browser timeouts...
-            //backup_flush();
-
-            //Check if we are into LOGS zone
-            //if ($this->tree[3] == "LOGS")                                                             //Debug
-            //    echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;".$tagName."&gt;<br />\n";   //Debug
-
-            //If we are under a LOG tag under a LOGS zone, accumule it
-            if (isset($this->tree[4]) and isset($this->tree[3])) {
-                if (($this->tree[4] == "LOG") and ($this->tree[3] == "LOGS")) {
-                    if (!isset($this->temp)) {
-                        $this->temp = "";
-                    }
-                    $this->temp .= "<".$tagName.">";
-                }
-            }
-        }
-
-        //This is the startTag default handler we use when $todo is undefined
-        function startElement($parser, $tagName, $attrs) {
-            $this->level++;
-            $this->tree[$this->level] = $tagName;
-
-            //Output something to avoid browser timeouts...
-            //backup_flush();
-
-            echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;".$tagName."&gt;<br />\n";   //Debug
-        }
-
-        //This is the endTag handler we use where we are reading the info zone ($todo="INFO")
-        function endElementInfo($parser, $tagName) {
-            //Check if we are into INFO zone
-            if ($this->tree[2] == "INFO") {
-                //if (trim($this->content))                                                                     //Debug
-                //    echo "C".str_repeat("&nbsp;",($this->level+2)*2).$this->getContents()."<br />\n";           //Debug
-                //echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;/".$tagName."&gt;<br />\n";          //Debug
-                //Dependig of different combinations, do different things
-                if ($this->level == 3) {
-                    switch ($tagName) {
-                        case "NAME":
-                            $this->info->backup_name = $this->getContents();
-                            break;
-                        case "MOODLE_VERSION":
-                            $this->info->backup_moodle_version = $this->getContents();
-                            break;
-                        case "MOODLE_RELEASE":
-                            $this->info->backup_moodle_release = $this->getContents();
-                            break;
-                        case "BACKUP_VERSION":
-                            $this->info->backup_backup_version = $this->getContents();
-                            break;
-                        case "BACKUP_RELEASE":
-                            $this->info->backup_backup_release = $this->getContents();
-                            break;
-                        case "DATE":
-                            $this->info->backup_date = $this->getContents();
-                            break;
-                        case "ORIGINAL_WWWROOT":
-                            $this->info->original_wwwroot = $this->getContents();
-                            break;
-                        case "ORIGINAL_SITE_IDENTIFIER_HASH":
-                            $this->info->original_siteidentifier = $this->getContents();
-                            break;
-                        case "MNET_REMOTEUSERS":
-                            $this->info->mnet_remoteusers = $this->getContents();
-                            break;
-                    }
-                }
-                if ($this->tree[3] == "DETAILS") {
-                    if ($this->level == 4) {
-                        switch ($tagName) {
-                            case "METACOURSE":
-                                $this->info->backup_metacourse = $this->getContents();
-                                break;
-                            case "USERS":
-                                $this->info->backup_users = $this->getContents();
-                                break;
-                            case "LOGS":
-                                $this->info->backup_logs = $this->getContents();
-                                break;
-                            case "USERFILES":
-                                $this->info->backup_user_files = $this->getContents();
-                                break;
-                            case "COURSEFILES":
-                                $this->info->backup_course_files = $this->getContents();
-                                break;
-                            case "SITEFILES":
-                                $this->info->backup_site_files = $this->getContents();
-                                break;
-                            case "GRADEBOOKHISTORIES":
-                                $this->info->gradebook_histories = $this->getContents();
-                                break;
-                            case "MESSAGES":
-                                $this->info->backup_messages = $this->getContents();
-                                break;
-                            case "BLOGS":
-                                $this->info->backup_blogs = $this->getContents();
-                                break;
-                            case 'BLOCKFORMAT':
-                                $this->info->backup_block_format = $this->getContents();
-                                break;
-                        }
-                    }
-                    if ($this->level == 5) {
-                        switch ($tagName) {
-                            case "NAME":
-                                $this->info->tempName = $this->getContents();
-                                break;
-                            case "INCLUDED":
-                                $this->info->mods[$this->info->tempName]->backup = $this->getContents();
-                                break;
-                            case "USERINFO":
-                                $this->info->mods[$this->info->tempName]->userinfo = $this->getContents();
-                                break;
-                        }
-                    }
-                    if ($this->level == 7) {
-                        switch ($tagName) {
-                            case "ID":
-                                $this->info->tempId = $this->getContents();
-                                $this->info->mods[$this->info->tempName]->instances[$this->info->tempId]->id = $this->info->tempId;
-                                break;
-                            case "NAME":
-                                $this->info->mods[$this->info->tempName]->instances[$this->info->tempId]->name = $this->getContents();
-                                break;
-                            case "INCLUDED":
-                                $this->info->mods[$this->info->tempName]->instances[$this->info->tempId]->backup = $this->getContents();
-                                break;
-                            case "USERINFO":
-                                $this->info->mods[$this->info->tempName]->instances[$this->info->tempId]->userinfo = $this->getContents();
-                                break;
-                        }
-                    }
-                }
-            }
-
-            //Stop parsing if $todo = INFO and tagName = INFO (en of the tag, of course)
-            //Speed up a lot (avoid parse all)
-            if ($tagName == "INFO") {
-                $this->finished = true;
-            }
-
-            //Clear things
-            $this->tree[$this->level] = "";
-            $this->level--;
-            $this->content = "";
-
-        }
-
-        function endElementRoles($parser, $tagName) {
-            //Check if we are into ROLES zone
-            if ($this->tree[2] == "ROLES") {
-
-                if ($this->tree[3] == "ROLE") {
-                    if ($this->level == 4) {
-                        switch ($tagName) {
-                            case "ID": // this is the old id
-                                $this->info->tempid = $this->getContents();
-                                $this->info->roles[$this->info->tempid]->id = $this->info->tempid;
-                                break;
-                            case "NAME":
-                                $this->info->roles[$this->info->tempid]->name = $this->getContents();
-                                break;
-                            case "SHORTNAME":
-                                $this->info->roles[$this->info->tempid]->shortname = $this->getContents();
-                                break;
-                            case "NAMEINCOURSE": // custom name of the role in course
-                                $this->info->roles[$this->info->tempid]->nameincourse = $this->getContents();
-                                break;
-                        }
-                    }
-                    if ($this->level == 5) {
-                        switch ($tagName) {
-                            case "CONTEXTLEVEL":
-                                $this->info->roles[$this->info->tempid]->contextlevels[] = $this->getContents();
-                                break;
-                        }
-                    }
-                    if ($this->level == 6) {
-                        switch ($tagName) {
-                            case "NAME":
-                                $this->info->tempcapname = $this->getContents();
-                                $this->info->roles[$this->info->tempid]->capabilities[$this->info->tempcapname]->name = $this->getContents();
-                                break;
-                            case "PERMISSION":
-                                $this->info->roles[$this->info->tempid]->capabilities[$this->info->tempcapname]->permission = $this->getContents();
-                                break;
-                            case "TIMEMODIFIED":
-                                $this->info->roles[$this->info->tempid]->capabilities[$this->info->tempcapname]->timemodified = $this->getContents();
-                                break;
-                            case "MODIFIERID":
-                                $this->info->roles[$this->info->tempid]->capabilities[$this->info->tempcapname]->modifierid = $this->getContents();
-                                break;
-                        }
-                    }
-                }
-            }
-
-            //Stop parsing if $todo = ROLES and tagName = ROLES (en of the tag, of course)
-            //Speed up a lot (avoid parse all)
-            if ($tagName == "ROLES") {
-                $this->finished = true;
-            }
-
-            //Clear things
-            $this->tree[$this->level] = "";
-            $this->level--;
-            $this->content = "";
-
-        }
-
-        //This is the endTag handler we use where we are reading the course_header zone ($todo="COURSE_HEADER")
-        function endElementCourseHeader($parser, $tagName) {
-            //Check if we are into COURSE_HEADER zone
-            if ($this->tree[3] == "HEADER") {
-                //if (trim($this->content))                                                                     //Debug
-                //    echo "C".str_repeat("&nbsp;",($this->level+2)*2).$this->getContents()."<br />\n";           //Debug
-                //echo $this->level.str_repeat("&nbsp;",$this->level*2)."&lt;/".$tagName."&gt;<br />\n";          //Debug
-                //Dependig of different combinations, do different things
-                if ($this->level == 4) {
-                    switch ($tagName) {
-                        case "ID":
-                            $this->info->course_id = $this->getContents();
-                            break;
-                        case "PASSWORD":
-                            $this->info->course_password = $this->getContents();
-                            break;
-                        case "FULLNAME":
-                            $this->info->course_fullname = $this->getContents();
-                            break;
-                        case "SHORTNAME":
-                            $this->info->course_shortname = $this->getContents();
-                            break;
-                        case "IDNUMBER":
-                            $this->info->course_idnumber = $this->getContents();
-                            break;
-                        case "SUMMARY":
-                            $this->info->course_summary = $this->getContents();
-                            break;
-                        case "FORMAT":
-                            $this->info->course_format = $this->getContents();
-                            break;
-                        case "SHOWGRADES":
-                            $this->info->course_showgrades = $this->getContents();
-                            break;
-                        case "BLOCKINFO":
-                            $this->info->blockinfo = $this->getContents();
-                            break;
-                        case "NEWSITEMS":
-                            $this->info->course_newsitems = $this->getContents();
-                            break;
-                        case "GUEST":
-                            $this->info->course_guest = $this->getContents();
-                            break;
-                        case "STARTDATE":
-                            $this->info->course_startdate = $this->getContents();
-                            break;
-                        case "NUMSECTIONS":
-                            $this->info->course_numsections = $this->getContents();
-                            break;
-                        //case "SHOWRECENT":                                          INFO: This is out in 1.3
-                        //    $this->info->course_showrecent = $this->getContents();
-                        //    break;
-                        case "MAXBYTES":
-                            $this->info->course_maxbytes = $this->getContents();
-                            break;
-                        case "SHOWREPORTS":
-                            $this->info->course_showreports = $this->getContents();
-                            break;
-                        case "GROUPMODE":
-                            $this->info->course_groupmode = $this->getContents();
-                            break;
-                        case "GROUPMODEFORCE":
-                            $this->info->course_groupmodeforce = $this->getContents();
-                            break;
-                        case "DEFAULTGROUPINGID":
-                            $this->info->course_defaultgroupingid = $this->getContents();
-                            break;
-                        case "LANG":
-                            $this->info->course_lang = $this->getContents();
-                            break;
-                        case "THEME":
-                            $this->info->course_theme = $this->getContents();
-                            break;
-                        case "COST":
-                            $this->info->course_cost = $this->getContents();
-                            break;
-                        case "CURRENCY":
-                            $this->info->course_currency = $this->getContents();
-                            break;
-                        case "MARKER":
-                            $this->info->course_marker = $this->getContents();
-                            break;
-                        case "VISIBLE":
-                            $this->info->course_visible = $this->getContents();
-                            break;
-                        case "HIDDENSECTIONS":
-                            $this->info->course_hiddensections = $this->getContents();
-                            break;
-                        case "TIMECREATED":
-                            $this->info->course_timecreated = $this->getContents();
-                            break;
-                        case "TIMEMODIFIED":
-                            $this->info->course_timemodified = $this->getContents();
-                            break;
-                        case "METACOURSE":
-                            $this->info->course_metacourse = $this->getContents();
-                            break;
-                        case "EXPIRENOTIFY":
-                            $this->info->course_expirynotify = $this->getContents();
-                            break;
-                        case "NOTIFYSTUDENTS":
-                            $this->info->course_notifystudents = $this->getContents();
-                            break;
-                        case "EXPIRYTHRESHOLD":
-                            $this->info->course_expirythreshold = $this->getContents();
-                            break;
-                        case "ENROLLABLE":
-                            $this->info->course_enrollable = $this->getContents();
-                            break;
-                        case "ENROLSTARTDATE":
-                            $this->info->course_enrolstartdate = $this->getContents();
-                            break;
-                        case "ENROLENDDATE":
-                            $this->info->course_enrolenddate = $this->getContents();
-                            break;
-                        case "ENROLPERIOD":
-                            $this->info->course_enrolperiod = $this->getContents();
-                            break;
-                        case "ENABLECOMPLETION":
-                            $this->info->course_enablecompletion = $this->getContents();
-                            break;
-                    }
-                }
-                if ($this->tree[4] == "CATEGORY") {
-                    if ($this->level == 5) {
-                        switch ($tagName) {
-                            case "ID":
-                                $this->info->category->id = $this->getContents();
-                                break;
-                            case "NAME":
-                                $this->info->category->name = $this->getContents();
-                                break;
-                        }
-                    }
-                }
-
-                if ($this->tree[4] == "ROLES_ASSIGNMENTS") {
-                    if ($this->level == 6) {
-                        switch ($tagName) {
-                            case "NAME":
-                                $this->info->tempname = $this->getContents();
-                            break;
-                            case "SHORTNAME":
-                                $this->info->tempshortname = $this->getContents();
-                            break;
-                            case "ID":
-                                $this->info->tempid = $this->getContents();
-                            break;
-                        }
-                    }
-
-                    if ($this->level == 8) {
-                        switch ($tagName) {
-                            case "USERID":
-                                $this->info->roleassignments[$this->info->tempid]->name = $this->info->tempname;
-                                $this->info->roleassignments[$this->info->tempid]->shortname = $this->info->tempshortname;
-                                $this->info->tempuser = $this->getContents();
-                                $this->info->roleassignments[$this->info->tempid]->assignments[$this->info->tempuser]->userid = $this->getContents();
-                            break;
-                            case "TIMESTART":
-                                $this->info->roleassignments[$this->info->tempid]->assignments[$this->info->tempuser]->timestart = $this->getContents();
-                            break;
-                            case "TIMEEND":
-                                $this->info->roleassignments[$this->info->tempid]->assignments[$this->info->tempuser]->timeend = $this->getContents();
-                            break;
-                            case "TIMEMODIFIED":
-                                $this->info->roleassignments[$this->info->tempid]->assignments[$this->info->tempuser]->timemodified = $this->getContents();
-                            break;
-                            case "MODIFIERID":
-                                $this->info->roleassignments[$this->info->tempid]->assignments[$this->info->tempuser]->modifierid = $this->getContents();
-                            break;
-                            case "ENROL":
-                                $this->info->roleassignments[$this->info->tempid]->assignments[$this->info->tempuser]->enrol = $this->getContents();
-                            break;
-                            case "SORTORDER":
-                                $this->info->roleassignments[$this->info->tempid]->assignments[$this->info->tempuser]->sortorder = $this->getContents();
-                            break;
+            //If we have info, then process messages & contacts
+            if ($info > 0) {
+             &