diff --git a/admin/index.php b/admin/index.php
index 6bfba86..b5a4b1d 100644
--- a/admin/index.php
+++ b/admin/index.php
@@ -189,9 +189,8 @@
     /// Continue with the instalation
         $db->debug = false;
         if ($status) {
-            //ugly hack - install new groups: MDL-9217
-            require_once("$CFG->dirroot/group/db/upgrade.php");
-            install_group_db();
+
+            /// Groups install is now in core above.
 
             // Install the roles system.
             moodle_install_roles();
@@ -327,9 +326,9 @@
             /// If successful, continue upgrading roles and setting everything properly
                 if ($status) {
                     if (empty($CFG->rolesactive)) {
-                        //ugly hack - upgrade to new groups (from 1.6) : MDL-9217
-                        require_once("$CFG->dirroot/group/db/upgrade.php");
-                        install_group_db();
+
+                        /// Groups upgrade is now in core above.
+
                         // Upgrade to the roles system.
                         moodle_install_roles();
                         set_config('rolesactive', 1);
@@ -380,9 +379,7 @@
         }
     }
 
-/// ugly hack - convert to new groups if upgrading from 1.7; must be reworked
-    require_once("$CFG->dirroot/group/db/upgrade.php");
-    upgrade_group_db("$CFG->wwwroot/$CFG->admin/index.php");  // Return here afterwards
+/// Groups install/upgrade is now in core above.
 
 
 /// Find and check all main modules and load them up or upgrade them if necessary
diff --git a/calendar/lib.php b/calendar/lib.php
index caef701..b94e021 100644
--- a/calendar/lib.php
+++ b/calendar/lib.php
@@ -1315,8 +1315,8 @@ function calendar_set_filters(&$courses, &$group, &$user, $courseeventsfrom = NU
             }
             
             if (!empty($groupids)) {
-                $sql = "SELECT id, groupid 
-                        FROM {$CFG->prefix}groups_courses_groups
+                $sql = "SELECT id 
+                        FROM {$CFG->prefix}groups
                         WHERE courseid IN (".implode(',', $groupids).')';
     
                 if ($grouprecords= get_records_sql($sql)) {
diff --git a/group/db/dbbasicgrouplib.php b/group/db/dbbasicgrouplib.php
index 735a531..06b5e9b 100644
--- a/group/db/dbbasicgrouplib.php
+++ b/group/db/dbbasicgrouplib.php
@@ -2,7 +2,7 @@
 /**
  * Functions to make changes to groups in the database i.e. functions that 
  * access tables:
- *     groups_courses_groups, groups and groups_members.
+ *     groups and groups_members.
  *
  * @copyright &copy; 2006 The Open University
  * @author J.White AT open.ac.uk
@@ -46,15 +46,15 @@ function groups_db_get_user($userid) {
     if (! $courseid) {
         return false;
     }
-    $records = get_records('groups_courses_groups', 'courseid', $courseid, 
-                           '', $fields='id, groupid');
+    $records = get_records('groups', 'courseid', $courseid, 
+                           '', $fields='id');
     if (! $records) {
         return false;
     }
     // Put the results into an array, note these are NOT 'group' objects.
     $groupids = array();
     foreach ($records as $record) {
-        array_push($groupids, $record->groupid);
+        array_push($groupids, $record->id);
     }
 
     return $groupids;
@@ -103,9 +103,7 @@ function groups_db_get_groups_for_user($userid, $courseid) {
                 FROM {$CFG->prefix}groups_members gm 
                 INNER JOIN {$CFG->prefix}groups g
                 ON gm.groupid = g.id
-                INNER JOIN {$CFG->prefix}groups_courses_groups cg
-                ON g.id = cg.groupid
-                WHERE cg.courseid  = '$courseid' AND gm.userid = '$userid'";
+                WHERE g.courseid  = '$courseid' AND gm.userid = '$userid'";
                 
         $groups = get_records_sql($sql);
         $groupids = groups_groups_to_groupids($groups);
@@ -198,10 +196,9 @@ function groups_db_group_matches($courseid, $grp_name, $grp_description) {
     global $CFG;
     $sql = "SELECT g.id, g.name, g.description
         FROM {$CFG->prefix}groups g
-        INNER JOIN {$CFG->prefix}groups_courses_groups cg ON g.id = cg.groupid
         WHERE g.name = '$grp_name'
         AND g.description = '$grp_description'
-        AND cg.courseid = '$courseid'";
+        AND g.courseid = '$courseid'";
     $records = get_records_sql($sql);
     $group = false;
     if ($records) {
@@ -218,9 +215,8 @@ function groups_db_group_name_exists($courseid, $grp_name) {
     global $CFG;
     $sql = "SELECT g.id, g.name
         FROM {$CFG->prefix}groups g
-        INNER JOIN {$CFG->prefix}groups_courses_groups cg ON g.id = cg.groupid
         WHERE g.name = '$grp_name'
-        AND cg.courseid = '$courseid'";
+        AND g.courseid = '$courseid'";
     $records = get_records_sql($sql);
     $group = false;
     if ($records) {
@@ -257,8 +253,8 @@ function groups_db_group_belongs_to_course($groupid, $courseid) {
     if (!$groupid or !$courseid) {
         $ismember = false;
     } else {
-        $ismember = record_exists($table = 'groups_courses_groups', 
-                                  'groupid', $groupid, 
+        $ismember = record_exists($table = 'groups', 
+                                  'id', $groupid, 
                                   'courseid', $courseid);
     }
 
@@ -291,21 +287,7 @@ function groups_db_create_group($courseid, $groupsettings=false, $copytime=false
         }
         //print_r($record);
         $groupid = insert_record('groups', $record);
-
-        if ($groupid != false) {
-            $record2 = new Object();
-            $record2->courseid = $courseid;
-            $record2->groupid = $groupid;
-            if ($copytime) {
-                $record2->timeadded = $record->timemodified;
-            } else {
-                $record2->timeadded = $now;
-            }
-            $groupadded = insert_record('groups_courses_groups', $record2);
-            if (!$groupadded) {
-                $groupid = false;
-            }
-        }
+        
     }
     return $groupid;
 }
@@ -324,21 +306,11 @@ function groups_db_upgrade_group($courseid, $group) {
 
     $r = addslashes_object($group);
     $sql = "INSERT INTO {$CFG->prefix}groups
-        (id,name,description, enrolmentkey,lang,theme,picture,hidepicture, timecreated,timemodified)
-        VALUES ('$r->id','$r->name','$r->description', '$r->enrolmentkey','$r->lang',
+        (id,courseid,name,description, enrolmentkey,lang,theme,picture,hidepicture, timecreated,timemodified)
+        VALUES ('$r->id','$r->courseid','$r->name','$r->description', '$r->enrolmentkey','$r->lang',
         '$r->theme','$r->picture','$r->hidepicture', '$r->timecreated','$r->timemodified')";
 
-    if ($result = execute_sql($sql)) {
-        $record2 = new Object();
-        $record2->courseid = $courseid;
-        $record2->groupid = $group->id;
-        $record2->timeadded = $group->timemodified;
-
-        $groupadded = insert_record('groups_courses_groups', $record2);
-        if (! $groupadded) {
-            $groupid = false;
-        }
-    }
+    $result = execute_sql($sql);
     return $group->id;
 }
 
@@ -461,13 +433,7 @@ function groups_db_delete_group($groupid) {
                 }
             }
         }
-
-        // Remove links with courses.
-        $results = delete_records('groups_courses_groups', 'groupid', $groupid);
-        if ($results == false) {
-            $success = false;
-        }
-
+        
         // Delete the group itself
         $results = delete_records($table = 'groups', $field1 = 'id', 
             $value1 = $groupid);
diff --git a/group/db/dbcourselib.php b/group/db/dbcourselib.php
deleted file mode 100644
index f87d8ed..0000000
--- a/group/db/dbcourselib.php
+++ /dev/null
@@ -1,10 +0,0 @@
-<?php
-// @@@ TO DO 
-function groups_db_get_forced_grouping($courseid) {
-}
-
-function groups__db_set_forced_grouping($courseid, $groupingid) {
-}
-
-
-?>
diff --git a/group/db/dbgroupinglib.php b/group/db/dbgroupinglib.php
index 361c0e6..10b6407 100644
--- a/group/db/dbgroupinglib.php
+++ b/group/db/dbgroupinglib.php
@@ -2,7 +2,7 @@
 /**
  * Functions to make changes to groupings in the database. In general these 
  * access the tables:
- *     groups_groupings, groups_courses_groupings and groups_groupings_groups
+ *     groups_groupings, groups_courses_groupings and groupings_groups
  * although some access all the tables that store information about groups.
  *
  * @copyright &copy; 2006 The Open University
@@ -54,7 +54,7 @@ function groups_db_get_groups_in_grouping($groupingid) {
         $groupid = false;
     } else {
 
-        $groups = get_records('groups_groupings_groups', 'groupingid ', 
+        $groups = get_records('groupings_groups', 'groupingid ', 
                               $groupingid, '', $fields='id, groupid');
         if (!$groups) {
             $groupids = false;
@@ -81,7 +81,7 @@ function groups_db_get_groupings_for_group($groupid) {
     if (!$groupid) {
         $groupingids = false;
     } else {
-        $groupings = get_records('groups_groupings_groups', 'groupid ', 
+        $groupings = get_records('groupings_groups', 'groupid ', 
             $groupid, '', $fields='id, groupingid');
         if (!$groupings) {
             $groupingids = false;
@@ -173,7 +173,7 @@ function groups_db_grouping_exists($groupingid) {
     if (!$groupid) {
         $isingrouping = false;
     } else {
-        $isingrouping = record_exists('groups_groupings_groups', 'groupid', 
+        $isingrouping = record_exists('groupings_groups', 'groupid', 
                                   $groupid);
     }
     
@@ -192,7 +192,7 @@ function groups_db_grouping_exists($groupingid) {
     if (!$groupid or !$groupingid) {
         $isingrouping = false;
     } else {
-        $isingrouping = record_exists('groups_groupings_groups', 'groupid', 
+        $isingrouping = record_exists('groupings_groups', 'groupid', 
                                   $groupid, 'groupingid', $groupingid);
     }
     
@@ -213,7 +213,7 @@ function groups_db_grouping_exists($groupingid) {
     } else {
         global $CFG;
         $sql = "SELECT gm.id
-        FROM {$CFG->prefix}groups_groupings_groups gg
+        FROM {$CFG->prefix}groupings_groups gg
         INNER JOIN {$CFG->prefix}groups_members gm
         ON gg.groupid = gm.groupid
         WHERE gm.userid = '$userid' AND gg.groupingid = '$groupingid'";
@@ -304,7 +304,7 @@ function groups_db_add_group_to_grouping($groupid, $groupingid) {
         $record->groupid = $groupid;
         $record->timeadded = time();
 
-        $results = insert_record('groups_groupings_groups', $record);
+        $results = insert_record('groupings_groups', $record);
         if (!$results) {
             $success = false;
         }
@@ -379,7 +379,7 @@ function groups_db_remove_group_from_grouping($groupid, $groupingid) {
     if (!$groupingid or !$groupid) {
         $success = false;
     } else {
-        $results = delete_records('groups_groupings_groups', 'groupid', 
+        $results = delete_records('groupings_groups', 'groupid', 
             $groupid, 'groupingid', $groupingid);
         // delete_records returns an array of the results from the sql call, 
         // not a boolean, so we have to set our return variable
@@ -410,7 +410,7 @@ function groups_db_delete_grouping($groupingid) {
             $success = false;
         }                           
                
-        $results = delete_records('groups_groupings_groups', 'groupingid', 
+        $results = delete_records('groupings_groups', 'groupingid', 
                                   $groupingid);
         if ($results == false) {
             $success = false;
diff --git a/group/db/install.xml b/group/db/install.xml
deleted file mode 100644
index c7de130..0000000
--- a/group/db/install.xml
+++ /dev/null
@@ -1,112 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<XMLDB PATH="group/db" VERSION="20070122" COMMENT="XMLDB file for Moodle groups."
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:noNamespaceSchemaLocation="../../lib/xmldb/xmldb.xsd"
->
-  <TABLES>
-    <TABLE NAME="groups" COMMENT="Each record represents a group." NEXT="groups_groupings">
-      <FIELDS>
-        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" ENUM="false" NEXT="name"/>
-        <FIELD NAME="name" TYPE="char" LENGTH="254" NOTNULL="true" SEQUENCE="false" ENUM="false" COMMENT="Short human readable unique name for the group." PREVIOUS="id" NEXT="description"/>
-        <FIELD NAME="description" TYPE="text" LENGTH="small" NOTNULL="false" SEQUENCE="false" ENUM="false" PREVIOUS="name" NEXT="enrolmentkey"/>
-        <FIELD NAME="enrolmentkey" TYPE="char" LENGTH="50" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="description" NEXT="lang"/>
-        <FIELD NAME="lang" TYPE="char" LENGTH="30" NOTNULL="true" DEFAULT="en" SEQUENCE="false" ENUM="false" PREVIOUS="enrolmentkey" NEXT="theme"/>
-        <FIELD NAME="theme" TYPE="char" LENGTH="50" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="lang" NEXT="picture"/>
-        <FIELD NAME="picture" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="theme" NEXT="hidepicture"/>
-        <FIELD NAME="hidepicture" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="picture" NEXT="timecreated"/>
-        <FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="hidepicture" NEXT="timemodified"/>
-        <FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="timecreated"/>
-      </FIELDS>
-      <KEYS>
-        <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for groups"/>
-      </KEYS>
-    </TABLE>
-    <TABLE NAME="groups_groupings" COMMENT="A grouping is a collection of groups." PREVIOUS="groups" NEXT="groups_members">
-      <FIELDS>
-        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" SEQUENCE="true" ENUM="false" COMMENT="id of the table, please edit me" NEXT="name"/>
-        <FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" ENUM="false" COMMENT="Short human readable unique name for group." PREVIOUS="id" NEXT="description"/>
-        <FIELD NAME="description" TYPE="text" LENGTH="small" NOTNULL="false" SEQUENCE="false" ENUM="false" PREVIOUS="name" NEXT="timecreated"/>
-        <FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="description" NEXT="viewowngroup"/>
-        <FIELD NAME="viewowngroup" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="1" SEQUENCE="false" ENUM="false" PREVIOUS="timecreated" NEXT="viewallgroupsmembers"/>
-        <FIELD NAME="viewallgroupsmembers" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="viewowngroup" NEXT="viewallgroupsactivities"/>
-        <FIELD NAME="viewallgroupsactivities" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="viewallgroupsmembers" NEXT="teachersgroupmark"/>
-        <FIELD NAME="teachersgroupmark" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="viewallgroupsactivities" NEXT="teachersgroupview"/>
-        <FIELD NAME="teachersgroupview" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="teachersgroupmark" NEXT="teachersoverride"/>
-        <FIELD NAME="teachersoverride" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="teachersgroupview" NEXT="teacherdeletable"/>
-        <FIELD NAME="teacherdeletable" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="teachersoverride"/>
-      </FIELDS>
-      <KEYS>
-        <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for groups_groupings"/>
-      </KEYS>
-    </TABLE>
-    <TABLE NAME="groups_members" COMMENT="Link a user to a group." PREVIOUS="groups_groupings" NEXT="groups_courses_groups">
-      <FIELDS>
-        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" ENUM="false" NEXT="groupid"/>
-        <FIELD NAME="groupid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="id" NEXT="userid"/>
-        <FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="groupid" NEXT="timeadded"/>
-        <FIELD NAME="timeadded" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="userid"/>
-      </FIELDS>
-      <KEYS>
-        <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for groups_members" NEXT="groupid"/>
-        <KEY NAME="groupid" TYPE="foreign" FIELDS="groupid" REFTABLE="groups" REFFIELDS="id" PREVIOUS="primary" NEXT="userid"/>
-        <KEY NAME="userid" TYPE="foreign" FIELDS="userid" REFTABLE="user" REFFIELDS="id" PREVIOUS="groupid"/>
-      </KEYS>
-      <INDEXES>
-        <INDEX NAME="groupid-courseid" UNIQUE="true" FIELDS="groupid, userid"/>
-      </INDEXES>
-    </TABLE>
-    <TABLE NAME="groups_courses_groups" COMMENT="Link a group to a course (or the site)." PREVIOUS="groups_members" NEXT="groups_courses_groupings">
-      <FIELDS>
-        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" SEQUENCE="true" ENUM="false" COMMENT="id of the table, please edit me" NEXT="courseid"/>
-        <FIELD NAME="courseid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="id" NEXT="groupid"/>
-        <FIELD NAME="groupid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="Default comment for the field, please edit me" PREVIOUS="courseid"/>
-      </FIELDS>
-      <KEYS>
-        <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for groups_courses_groups" NEXT="courseid"/>
-        <KEY NAME="courseid" TYPE="foreign" FIELDS="courseid" REFTABLE="course" REFFIELDS="id" PREVIOUS="primary" NEXT="groupid"/>
-        <KEY NAME="groupid" TYPE="foreign" FIELDS="groupid" REFTABLE="groups" REFFIELDS="id" PREVIOUS="courseid"/>
-      </KEYS>
-      <INDEXES>
-        <INDEX NAME="courseid-groupid" UNIQUE="true" FIELDS="courseid, groupid"/>
-      </INDEXES>
-    </TABLE>
-    <TABLE NAME="groups_courses_groupings" COMMENT="Link a grouping to a course (or the site)." PREVIOUS="groups_courses_groups" NEXT="groups_groupings_groups">
-      <FIELDS>
-        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" SEQUENCE="true" ENUM="false" COMMENT="id of the table, please edit me" NEXT="courseid"/>
-        <FIELD NAME="courseid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="id" NEXT="groupingid"/>
-        <FIELD NAME="groupingid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" ENUM="false" PREVIOUS="courseid"/>
-      </FIELDS>
-      <KEYS>
-        <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for groups_courses_groupings" NEXT="courseid"/>
-        <KEY NAME="courseid" TYPE="foreign" FIELDS="courseid" REFTABLE="course" REFFIELDS="id" PREVIOUS="primary" NEXT="groupingid"/>
-        <KEY NAME="groupingid" TYPE="foreign" FIELDS="groupingid" REFTABLE="groups_groupings" REFFIELDS="id" PREVIOUS="courseid"/>
-      </KEYS>
-      <INDEXES>
-        <INDEX NAME="courseid-groupingid" UNIQUE="true" FIELDS="courseid, groupingid"/>
-      </INDEXES>
-    </TABLE>
-    <TABLE NAME="groups_groupings_groups" COMMENT="Link a group to a grouping." PREVIOUS="groups_courses_groupings">
-      <FIELDS>
-        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" SEQUENCE="true" ENUM="false" COMMENT="id of the table, please edit me" NEXT="groupingid"/>
-        <FIELD NAME="groupingid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="id" NEXT="groupid"/>
-        <FIELD NAME="groupid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" ENUM="false" PREVIOUS="groupingid" NEXT="timeadded"/>
-        <FIELD NAME="timeadded" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="groupid"/>
-      </FIELDS>
-      <KEYS>
-        <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for groups_groupings_groups" NEXT="groupingid"/>
-        <KEY NAME="groupingid" TYPE="foreign" FIELDS="groupingid" REFTABLE="groups_groupings" REFFIELDS="id" PREVIOUS="primary" NEXT="groupid"/>
-        <KEY NAME="groupid" TYPE="foreign" FIELDS="groupid" REFTABLE="groups" REFFIELDS="id" PREVIOUS="groupingid"/>
-      </KEYS>
-      <INDEXES>
-        <INDEX NAME="groupingid-groupid" UNIQUE="true" FIELDS="groupingid, groupid"/>
-      </INDEXES>
-    </TABLE>
-  </TABLES>
-  <STATEMENTS>
-    <STATEMENT NAME="insert log_display" TYPE="insert" TABLE="log_display" COMMENT="Initial insert of records on table log_display">
-      <SENTENCES>
-        <SENTENCE TEXT="(module, action, mtable, field) VALUES ('group', 'view', 'groups', 'name')" />
-      </SENTENCES>
-    </STATEMENT>
-  </STATEMENTS>
-</XMLDB>
\ No newline at end of file
diff --git a/group/lib/courselib.php b/group/lib/courselib.php
deleted file mode 100644
index b257b56..0000000
--- a/group/lib/courselib.php
+++ /dev/null
@@ -1,12 +0,0 @@
-<?php
-// @@@ TO DO 
-function groups_get_forced_grouping($courseid) {
-}
-
-function groups_set_forced_grouping($courseid, $groupingid) {
-}
-
-function groups_course_print_group_selector($userid, $courseid, $permissiontype) {
-}
-
-?>
diff --git a/group/lib/groupinglib.php b/group/lib/groupinglib.php
index 4241692..ddf450c 100644
--- a/group/lib/groupinglib.php
+++ b/group/lib/groupinglib.php
@@ -63,7 +63,7 @@ function groups_get_groups_in_grouping_records($groupingid) {
     if (! $groupingid) {
         return false;
     }
-    $grouping_groups = get_records('groups_groupings_groups', 'groupingid ', 
+    $grouping_groups = get_records('groupings_groups', 'groupingid ', 
                               $groupingid, '', $fields='id, groupid, timeadded');
 
     return $grouping_groups;
@@ -129,7 +129,7 @@ function groups_get_grouping_name($groupingid) {
 function groups_get_groups_for_user_in_grouping($userid, $groupingid) {
     global $CFG;
     $sql = "SELECT gg.groupid
-        FROM {$CFG->prefix}groups_groupings_groups gg
+        FROM {$CFG->prefix}groupings_groups gg
         INNER JOIN {$CFG->prefix}groups_members gm ON gm.groupid = gg.groupid
         WHERE gm.userid = '$userid'
         AND gg.groupingid = '$groupingid'";
@@ -167,14 +167,13 @@ function groups_get_groups_not_in_any_grouping($courseid) {
     $join = '';
     $where= '';
     if ($courseid) {
-        $join = "INNER JOIN {$CFG->prefix}groups_courses_groups cg ON g.id = cg.groupid";
-        $where= "AND cg.courseid = '$courseid'";
+        $where= "AND g.courseid = '$courseid'";
     }
     $sql = "SELECT g.id
         FROM {$CFG->prefix}groups g
         $join
         WHERE g.id NOT IN 
-        (SELECT groupid FROM {$CFG->prefix}groups_groupings_groups)
+        (SELECT groupid FROM {$CFG->prefix}groupings_groups)
         $where";
 
     $records = get_records_sql($sql);
diff --git a/group/lib/utillib.php b/group/lib/utillib.php
index bf4cb8a..cf3a8e5 100644
--- a/group/lib/utillib.php
+++ b/group/lib/utillib.php
@@ -46,9 +46,9 @@ function groups_count_groups_in_grouping($groupingid, $courseid) {
         
         return count($groupids);
     } elseif (GROUP_ANY_GROUPING == $groupingid) {
-        return count_records('groups_courses_groups', 'courseid', $courseid);
+        return count_records('groups', 'courseid', $courseid);
     } else {
-        return count_records('groups_groupings_groups', 'groupingid ', $groupingid);
+        return count_records('groupings_groups', 'groupingid ', $groupingid);
     }
 }
 
@@ -294,7 +294,7 @@ function groups_get_course_info($courseid){
  * Gets the course ID for a given group.
  */
 function groups_get_course($groupid) {
-    $course_group = get_record('groups_courses_groups', 'groupid', $groupid);
+    $course_group = get_record('groups', 'id', $groupid);
     if ($course_group) {
         return $course_group->courseid;
     }
diff --git a/group/overview.txt b/group/overview.txt
deleted file mode 100644
index fcb2301..0000000
--- a/group/overview.txt
+++ /dev/null
@@ -1,54 +0,0 @@
-Quick summary!
-
-See the wiki too - 
-
-http://docs.moodle.org/en/How_groups_work_in_Moodle
-http://docs.moodle.org/en/Groups_documentation_for_module_developers
-
-To install - run install.php. This create the appropriate database tables and 
-sets some default config for using an IMS Enterprise web service (in particular 
-the default setting is that such a web service is not called).
-
-The user interface for managing groups for a course is groupsui/index.php. 
-A grouping is just a set of groups - the idea is that you can have several 
-groupings for a course, and then choose different groupings for different 
-activities. 
-
-Note that installing this code does not enable you to actually use the groupings 
-with activity modules - this is coming :-)
-
-configui - This contains the user interface for changing the IMS Enterprise web 
-service config
-
-db - all the functions that access the database, only used internally. There are 
-basically six tables that this code deals with  groups_groups, 
-groups_courses_groups,groups_groups_users, groups_groupings  
-
-groupui - the user interface for managing the groups and groupings of a course. 
-This uses Ajax so most of the code for the user interface is in the javascript 
-files - the PHP files just send back an appropriate XML response to specific
-POST requests. You'll probably need to know the basics of how Ajax works to 
-understand the Javascript. 
-
-lib - The main libraries for the user interface and other moodle code to user. 
--- basicgrouplib.php contains the basic functions for  adding users to groups, 
-deleting groups etc.
--- groupinglib.php contains the basic function for groupings e.g. creating 
-groupings, adding groups to groupings
--- extendedgrouplib.php contains other functions that are useful and use the 
-basic group and grouping functions
--- lib.php is just there to let you include all the libraries more easily
--- utillib.php contains functions that are handy but don't use any of the group 
-or grouping library function e.g. 
-things like getting the names of users 
--- configlib.php - Contains wrapper functions for getting and setting config
-
-unittests - This directory needs a bit of sorting out, and I've just discovered 
-that I've broken one of the main 
-tests...
- 
-
-strings.php - This is stuff that will need to go in the language files - it's 
-here for convenience while I'm doing the
-development. 
-
diff --git a/group/version.php b/group/version.php
deleted file mode 100644
index 1f4cb50..0000000
--- a/group/version.php
+++ /dev/null
@@ -1,11 +0,0 @@
-<?php
-
-////////////////////////////////////////////////////////////////////////////////
-//  Code fragment to define the group version etc.
-//  This fragment is called by /admin/index.php
-////////////////////////////////////////////////////////////////////////////////
-
-$group_version  = 2007012400;
-//$module->requires = 2006120400;  // Requires this Moodle version
-
-?>
diff --git a/lib/db/install.xml b/lib/db/install.xml
index 64d0e38..b0d14ce 100644
--- a/lib/db/install.xml
+++ b/lib/db/install.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<XMLDB PATH="lib/db" VERSION="20070809" COMMENT="XMLDB file for core Moodle tables"
+<XMLDB PATH="lib/db" VERSION="20070813" COMMENT="XMLDB file for core Moodle tables"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:noNamespaceSchemaLocation="../../lib/xmldb/xmldb.xsd"
 >
@@ -55,8 +55,9 @@
         <FIELD NAME="visible" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="1" SEQUENCE="false" ENUM="false" PREVIOUS="showreports" NEXT="hiddensections"/>
         <FIELD NAME="hiddensections" TYPE="int" LENGTH="2" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="visible" NEXT="groupmode"/>
         <FIELD NAME="groupmode" TYPE="int" LENGTH="4" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="hiddensections" NEXT="groupmodeforce"/>
-        <FIELD NAME="groupmodeforce" TYPE="int" LENGTH="4" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="groupmode" NEXT="lang"/>
-        <FIELD NAME="lang" TYPE="char" LENGTH="30" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="groupmodeforce" NEXT="theme"/>
+        <FIELD NAME="groupmodeforce" TYPE="int" LENGTH="4" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="groupmode" NEXT="groupingid"/>
+        <FIELD NAME="groupingid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="groupmodeforce" NEXT="lang"/>
+        <FIELD NAME="lang" TYPE="char" LENGTH="30" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="groupingid" NEXT="theme"/>
         <FIELD NAME="theme" TYPE="char" LENGTH="50" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="lang" NEXT="cost"/>
         <FIELD NAME="cost" TYPE="char" LENGTH="10" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="theme" NEXT="currency"/>
         <FIELD NAME="currency" TYPE="char" LENGTH="3" NOTNULL="true" DEFAULT="USD" SEQUENCE="false" ENUM="false" PREVIOUS="cost" NEXT="timecreated"/>
@@ -75,7 +76,8 @@
         <FIELD NAME="defaultrole" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" COMMENT="The default role given to participants who self-enrol" PREVIOUS="enrol"/>
       </FIELDS>
       <KEYS>
-        <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for course"/>
+        <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for course" NEXT="groupingid"/>
+        <KEY NAME="groupingid" TYPE="foreign" FIELDS="groupingid" REFTABLE="groupings" REFFIELDS="id" PREVIOUS="primary"/>
       </KEYS>
       <INDEXES>
         <INDEX NAME="category" UNIQUE="false" FIELDS="category" NEXT="idnumber"/>
@@ -143,10 +145,13 @@
         <FIELD NAME="indent" TYPE="int" LENGTH="5" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="score" NEXT="visible"/>
         <FIELD NAME="visible" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="false" DEFAULT="1" SEQUENCE="false" ENUM="false" PREVIOUS="indent" NEXT="visibleold"/>
         <FIELD NAME="visibleold" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="false" DEFAULT="1" SEQUENCE="false" ENUM="false" PREVIOUS="visible" NEXT="groupmode"/>
-        <FIELD NAME="groupmode" TYPE="int" LENGTH="4" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="visibleold"/>
+        <FIELD NAME="groupmode" TYPE="int" LENGTH="4" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="visibleold" NEXT="groupingid"/>
+        <FIELD NAME="groupingid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="groupmode" NEXT="grouponly"/>
+        <FIELD NAME="grouponly" TYPE="int" LENGTH="4" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="groupingid"/>
       </FIELDS>
       <KEYS>
-        <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for course_modules"/>
+        <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for course_modules" NEXT="groupingid"/>
+        <KEY NAME="groupingid" TYPE="foreign" FIELDS="groupingid" REFTABLE="groupings" REFFIELDS="id" PREVIOUS="primary"/>
       </KEYS>
       <INDEXES>
         <INDEX NAME="visible" UNIQUE="false" FIELDS="visible" NEXT="course"/>
@@ -1643,7 +1648,7 @@
         <INDEX NAME="tagid" UNIQUE="true" FIELDS="tagid" COMMENT="tagid"/>
       </INDEXES>
     </TABLE>
-    <TABLE NAME="tag_instance" COMMENT="tag_instance table holds the information of associations between tags and other items" PREVIOUS="tag_correlation">
+    <TABLE NAME="tag_instance" COMMENT="tag_instance table holds the information of associations between tags and other items" PREVIOUS="tag_correlation" NEXT="groups">
       <FIELDS>
         <FIELD NAME="id" TYPE="int" LENGTH="11" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" ENUM="false" NEXT="tagid"/>
         <FIELD NAME="tagid" TYPE="int" LENGTH="11" NOTNULL="true" UNSIGNED="false" SEQUENCE="false" ENUM="false" PREVIOUS="id" NEXT="itemtype"/>
@@ -1657,6 +1662,67 @@
         <INDEX NAME="tagiditem" UNIQUE="true" FIELDS="tagid, itemtype, itemid"/>
       </INDEXES>
     </TABLE>
+    <TABLE NAME="groups" COMMENT="Each record represents a group." PREVIOUS="tag_instance" NEXT="groupings">
+      <FIELDS>
+        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" ENUM="false" NEXT="courseid"/>
+        <FIELD NAME="courseid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" ENUM="false" PREVIOUS="id" NEXT="name"/>
+        <FIELD NAME="name" TYPE="char" LENGTH="254" NOTNULL="true" SEQUENCE="false" ENUM="false" COMMENT="Short human readable unique name for the group." PREVIOUS="courseid" NEXT="description"/>
+        <FIELD NAME="description" TYPE="text" LENGTH="small" NOTNULL="false" SEQUENCE="false" ENUM="false" PREVIOUS="name" NEXT="enrolmentkey"/>
+        <FIELD NAME="enrolmentkey" TYPE="char" LENGTH="50" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="description" NEXT="lang"/>
+        <FIELD NAME="lang" TYPE="char" LENGTH="30" NOTNULL="true" DEFAULT="en" SEQUENCE="false" ENUM="false" PREVIOUS="enrolmentkey" NEXT="theme"/>
+        <FIELD NAME="theme" TYPE="char" LENGTH="50" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="lang" NEXT="picture"/>
+        <FIELD NAME="picture" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="theme" NEXT="hidepicture"/>
+        <FIELD NAME="hidepicture" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="picture" NEXT="timecreated"/>
+        <FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="hidepicture" NEXT="timemodified"/>
+        <FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="timecreated"/>
+      </FIELDS>
+      <KEYS>
+        <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for groups." NEXT="courseid"/>
+        <KEY NAME="courseid" TYPE="foreign" FIELDS="courseid" REFTABLE="course" REFFIELDS="id" PREVIOUS="primary"/>
+      </KEYS>
+    </TABLE>
+    <TABLE NAME="groupings" COMMENT="A grouping is a collection of groups. WAS: groups_groupings" PREVIOUS="groups" NEXT="groups_members">
+      <FIELDS>
+        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" SEQUENCE="true" ENUM="false" COMMENT="id of the table, please edit me" NEXT="courseid"/>
+        <FIELD NAME="courseid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="id" NEXT="name"/>
+        <FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" ENUM="false" COMMENT="Short human readable unique name for group." PREVIOUS="courseid" NEXT="description"/>
+        <FIELD NAME="description" TYPE="text" LENGTH="small" NOTNULL="false" SEQUENCE="false" ENUM="false" PREVIOUS="name" NEXT="exclusivegroups"/>
+        <FIELD NAME="exclusivegroups" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="description" NEXT="maxgroupsize"/>
+        <FIELD NAME="maxgroupsize" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="exclusivegroups" NEXT="timecreated"/>
+        <FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="maxgroupsize" NEXT="timemodified"/>
+        <FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="timecreated"/>
+      </FIELDS>
+      <KEYS>
+        <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for groupings." NEXT="courseid"/>
+        <KEY NAME="courseid" TYPE="foreign" FIELDS="courseid" REFTABLE="course" REFFIELDS="id" PREVIOUS="primary"/>
+      </KEYS>
+    </TABLE>
+    <TABLE NAME="groups_members" COMMENT="Link a user to a group." PREVIOUS="groupings" NEXT="groupings_groups">
+      <FIELDS>
+        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" ENUM="false" NEXT="groupid"/>
+        <FIELD NAME="groupid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="id" NEXT="userid"/>
+        <FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="groupid" NEXT="timeadded"/>
+        <FIELD NAME="timeadded" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="userid"/>
+      </FIELDS>
+      <KEYS>
+        <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for groups_members" NEXT="groupid"/>
+        <KEY NAME="groupid" TYPE="foreign" FIELDS="groupid" REFTABLE="groups" REFFIELDS="id" PREVIOUS="primary" NEXT="userid"/>
+        <KEY NAME="userid" TYPE="foreign" FIELDS="userid" REFTABLE="user" REFFIELDS="id" PREVIOUS="groupid"/>
+      </KEYS>
+    </TABLE>
+    <TABLE NAME="groupings_groups" COMMENT="Link a grouping to a group (note, groups can be in multiple groupings ONLY in a course). WAS: groups_groupings_groups" PREVIOUS="groups_members">
+      <FIELDS>
+        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" SEQUENCE="true" ENUM="false" COMMENT="id of the table, please edit me" NEXT="groupingid"/>
+        <FIELD NAME="groupingid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="id" NEXT="groupid"/>
+        <FIELD NAME="groupid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="groupingid" NEXT="timeadded"/>
+        <FIELD NAME="timeadded" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="groupid"/>
+      </FIELDS>
+      <KEYS>
+        <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for groupings_groups" NEXT="groupingid"/>
+        <KEY NAME="groupingid" TYPE="foreign" FIELDS="groupingid" REFTABLE="groupings" REFFIELDS="id" PREVIOUS="primary" NEXT="groupid"/>
+        <KEY NAME="groupid" TYPE="foreign" FIELDS="groupid" REFTABLE="groups" REFFIELDS="id" PREVIOUS="groupingid"/>
+      </KEYS>
+    </TABLE>
   </TABLES>
   <STATEMENTS>
     <STATEMENT NAME="insert mnet_application" TYPE="insert" TABLE="mnet_application" COMMENT="Initial insert of records on table mnet_application" NEXT="insert log_display">
@@ -1683,7 +1749,8 @@
         <SENTENCE TEXT="(module, action, mtable, field) VALUES ('message', 'remove contact', 'user', 'CONCAT(firstname,&quot; &quot;,lastname)')" />
         <SENTENCE TEXT="(module, action, mtable, field) VALUES ('message', 'block contact', 'user', 'CONCAT(firstname,&quot; &quot;,lastname)')" />
         <SENTENCE TEXT="(module, action, mtable, field) VALUES ('message', 'unblock contact', 'user', 'CONCAT(firstname,&quot; &quot;,lastname)')" />
+        <SENTENCE TEXT="(module, action, mtable, field) VALUES ('group', 'view', 'groups', 'name')" />
       </SENTENCES>
     </STATEMENT>
   </STATEMENTS>
-</XMLDB>
\ No newline at end of file
+</XMLDB>
diff --git a/lib/db/upgrade.php b/lib/db/upgrade.php
index b5199f1..162c97f 100644
--- a/lib/db/upgrade.php
+++ b/lib/db/upgrade.php
@@ -972,7 +972,7 @@ function xmldb_main_upgrade($oldversion=0) {
 
     if ($result && $oldversion < 2007071607) {
         require_once($CFG->dirroot . '/question/upgrade.php');
-        $result = $result && question_remove_rqp_qtype_config_string();
+///        $result = $result && question_remove_rqp_qtype_config_string();
     }
 
     if ($result && $oldversion < 2007072200) {
@@ -1421,11 +1421,11 @@ function xmldb_main_upgrade($oldversion=0) {
                 if ($rs->RecordCount() > 0) {
                     while ($course = rs_fetch_next_record($rs)) {
                         // this function uses SQL only, it must not be changed after 1.9 goes stable!!
-                        if (!upgrade_18_gradebook($course->id)) {
+/*                        if (!upgrade_18_gradebook($course->id)) {
                             $result = false;
                             break;
                         }
-                    }
+*/                    }
                 }
                 rs_close($rs);
             }
@@ -1718,11 +1718,96 @@ function xmldb_main_upgrade($oldversion=0) {
         }
     }
 */
+
     if ($result && $oldversion < 2007081000) {
         require_once($CFG->dirroot . '/question/upgrade.php');
         $result = $result && question_upgrade_context_etc();
     }
 
+    if ($result && $oldversion < 2007081300) {
+        require_once($CFG->libdir.'/db/upgradelib.php');
+        // Flag for use later.
+        $ismoodle_18 = false;
+
+    /// IF 'groups_groupings' table exists, this is for 1.8.* only.
+        if (table_exists($table = new XMLDBTable('groups_groupings'))) {
+            $ismoodle_18 = true;
+
+        /// Delete keys & indexes - they may get in the way.            
+            $result = $result && upgrade_drop_keys_indexes_groups();
+
+            $result = $result && upgrade_18_groups($table);
+        }
+    /// ELSE, 1.7.*/1.6.*/1.5.* - create 'groupings'.
+        else {
+            $result = $result && upgrade_17_groups();
+        }
+    /// For both 1.8.* and 1.7.*/1.6.*..
+
+    /// Add groupingid field/f.key to 'course' table.
+        $table = new XMLDBTable('course');
+
+        $field = new XMLDBField('groupingid');
+        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', $prev='groupmodeforce');
+        $result = $result && add_field($table, $field);
+
+        $key = new XMLDBKey('groupingid');
+        $key->setAttributes(XMLDB_KEY_FOREIGN, array('groupingid'), 'groupings', array('id'));
+        $result = $result && add_key($table, $key);
+
+
+    /// Add grouping ID, grouponly field/f.key to 'course_modules' table.
+        //ALTER TABLE mdl_course_modules DROP COLUMN groupingid;
+        $table = new XMLDBTable('course_modules');
+
+        $field = new XMLDBField('groupingid');
+        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', $prev='groupmode');
+        $result = $result && add_field($table, $field);
+
+        $field = new XMLDBField('grouponly');
+        $field->setAttributes(XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', $prev='groupingid');
+        $result = $result && add_field($table, $field);
+
+        $key = new XMLDBKey('groupingid');
+        $key->setAttributes(XMLDB_KEY_FOREIGN, array('groupingid'), 'groupings', array('id'));
+        $result = $result && add_key($table, $key);
+
+        if ($ismoodle_18) {
+        /// Transfer course ID from 'mdl_groups_courses_groupings' to 'mdl_groupings'.
+            if (!$rs = get_recordset('groups_courses_groupings')) {
+                //ERROR: strange - did we already remove the tables?
+                return;
+            }
+            $db->debug = false;
+            if ($rs->RecordCount() > 0) {
+                while ($course_grouping = rs_fetch_next_record($rs)) {
+                    //Update record, overwrite the 'id' (not useful) with grouping ID.
+                    $course_grouping->id = $course_grouping->groupingid;
+                    $result = $result && update_record('groupings', $course_grouping);
+                    
+                /// And, add grouping IDs to 'course' table.
+                    $course = new object();
+                    $course->id = $course_grouping->courseid;
+                    $course->groupingid = $course_grouping->id;
+                    $result = $result && update_record('course', $course);
+                }
+            }
+            rs_close($rs);
+            $db->debug = true;
+/*
+        ///TODO: Delete old tables - uncomment only AFTER testing!
+            $result = $result && drop_table(new XMLDBTable('groups_courses_groups'));
+            $result = $result && drop_table(new XMLDBTable('groups_courses_groupings'));
+            $result = $result && drop_table(new XMLDBTable('groups_temp'));
+            $result = $result && drop_table(new XMLDBTable('groups_members_temp'));
+        
+            $result = $result && unset_config('group_version');
+*/
+        }
+    }
+    
+
+
     return $result;
 }
 
diff --git a/lib/db/upgradelib.php b/lib/db/upgradelib.php
index 1b8aeeb..f1ff170 100644
--- a/lib/db/upgradelib.php
+++ b/lib/db/upgradelib.php
@@ -174,4 +174,221 @@ function upgrade_18_gradebook($courseid) {
     return true;
 }
 
+
+
+/**
+ * Create new groupings tables for upgrade from 1.7.*|1.6.* and so on.
+ */
+function upgrade_17_groups() {
+    $result = true;
+
+/// Define table groupings to be created
+    $table = new XMLDBTable('groupings');
+
+/// Adding fields to table groupings
+    $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
+    $table->addFieldInfo('courseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
+    $table->addFieldInfo('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
+    $table->addFieldInfo('description', XMLDB_TYPE_TEXT, 'small', null, null, null, null, null, null);
+    $table->addFieldInfo('exclusivegroups', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
+    $table->addFieldInfo('maxgroupsize', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
+    $table->addFieldInfo('timecreated', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
+    $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
+
+/// Adding keys to table groupings
+    $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
+    $table->addKeyInfo('courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
+
+/// Launch create table for groupings
+    $result = $result && create_table($table);
+
+// ==========================================
+
+/// Define table groupings_groups to be created
+    $table = new XMLDBTable('groupings_groups');
+
+/// Adding fields to table groupings_groups
+    $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
+    $table->addFieldInfo('groupingid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
+    $table->addFieldInfo('groupid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
+    $table->addFieldInfo('timeadded', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
+
+/// Adding keys to table groupings_groups
+    $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
+    $table->addKeyInfo('groupingid', XMLDB_KEY_FOREIGN, array('groupingid'), 'groupings', array('id'));
+    $table->addKeyInfo('groupid', XMLDB_KEY_FOREIGN, array('groupid'), 'groups', array('id'));
+
+/// Launch create table for groupings_groups
+    $result = $result && create_table($table);
+
+    return $result;
+}
+
+/**
+ * Drop, add fields and rename tables for groups upgrade from 1.8.*
+ * @param XMLDBTable $table 'groups_groupings' table object.
+ */
+function upgrade_18_groups($table) {
+    global $CFG;
+    $result = true;
+
+/// Delete columns 'viewowngroup', etc.
+    $field = new XMLDBField('viewowngroup');
+    $field->setAttributes(XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, null, null, '0', $prev='timecreated');
+    $fields_r = array('viewowngroup', 'viewallgroupsmembers', 'viewallgroupsactivities', 
+            'teachersgroupmark', 'teachersgroupview', 'teachersoverride', 'teacherdeletable');
+    $result = $result && upgrade_drop_fields($table, $field, $fields_r);
+
+/// Add columns/key 'courseid', exclusivegroups, maxgroupsize, timemodified.
+    $field = new XMLDBField('courseid');
+    $field->setAttributes(XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0', $prev='id');
+    $result = $result && add_field($table, $field);
+
+    $key = new XMLDBKey('courseid');
+    $key->setAttributes(XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
+    $result = $result && add_key($table, $key);
+
+    $field = new XMLDBField('exclusivegroups');
+    $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', $prev='description');
+    $result = $result && add_field($table, $field);
+
+    $field = new XMLDBField('maxgroupsize');
+    $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', $prev='exclusivegroups');
+    $result = $result && add_field($table, $field);
+
+    $field = new XMLDBField('timemodified');
+    $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', $prev='timecreated');
+    $result = $result && add_field($table, $field);
+
+/// Rename to 'groupings'.
+    $result = $result && rename_table($table, 'groupings');
+
+
+/// Now, rename 'groups_groupings_groups' to 'groupings_groups' - confused yet?!
+    $result = $result && rename_table($table = new XMLDBTable('groups_groupings_groups'), 'groupings_groups');
+
+
+/// Transfer course ID from 'mdl_groups_courses_groups' to 'mdl_groups'.
+    if (!$rs = get_recordset('groups_courses_groups')) {
+        //ERROR: strange - did we already remove the tables?
+        return;
+    }
+    $db->debug = false;
+    if ($rs->RecordCount() > 0) {
+        while ($group = rs_fetch_next_record($rs)) {
+            //Update record, overwrite the 'id' (not useful) with group ID.
+            $group->id = $group->groupid;
+            $result = $result && update_record('groups', $group);
+        }
+    }
+    rs_close($rs);
+    $db->debug = true;
+
+    return $result;
+}
+
+/**
+ * Drop keys & indexes for groups upgrade from 1.8.*
+ */
+function upgrade_drop_keys_indexes_groups() {
+    $result = true;
+
+/// Define index groupid-courseid (unique) to be added to groups_members
+    $table = new XMLDBTable('groups_members');
+    $index = new XMLDBIndex('groupid-courseid');
+    $index->setAttributes(XMLDB_INDEX_UNIQUE, array('groupid', 'userid'));
+
+/// Launch add index groupid-courseid
+    $result = $result && drop_index($table, $index);
+
+/// Define key courseid (foreign) to be added to groups_courses_groups
+    $table = new XMLDBTable('groups_courses_groups');
+    $key = new XMLDBKey('courseid');
+    $key->setAttributes(XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
+
+/// Launch add key courseid
+    $result = $result && drop_key($table, $key);
+
+/// Define key groupid (foreign) to be added to groups_courses_groups
+    $key = new XMLDBKey('groupid');
+    $key->setAttributes(XMLDB_KEY_FOREIGN, array('groupid'), 'groups', array('id'));
+
+/// Launch add key groupid
+    $result = $result && drop_key($table, $key);
+
+/// Define index courseid-groupid (unique) to be added to groups_courses_groups
+    $index = new XMLDBIndex('courseid-groupid');
+    $index->setAttributes(XMLDB_INDEX_UNIQUE, array('courseid', 'groupid'));
+
+/// Launch add index courseid-groupid
+    $result = $result && drop_index($table, $index);
+
+/// Define key courseid (foreign) to be added to groups_courses_groupings
+    $table = new XMLDBTable('groups_courses_groupings');
+    $key = new XMLDBKey('courseid');
+    $key->setAttributes(XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
+
+/// Launch add key courseid
+    $result = $result && drop_key($table, $key);
+
+/// Define key groupingid (foreign) to be added to groups_courses_groupings
+    $key = new XMLDBKey('groupingid');
+    $key->setAttributes(XMLDB_KEY_FOREIGN, array('groupingid'), 'groups_groupings', array('id'));
+
+/// Launch add key groupingid
+    $result = $result && drop_key($table, $key);
+
+/// Define index courseid-groupingid (unique) to be added to groups_courses_groupings
+    $index = new XMLDBIndex('courseid-groupingid');
+    $index->setAttributes(XMLDB_INDEX_UNIQUE, array('courseid', 'groupingid'));
+
+/// Launch add index courseid-groupingid
+    $result = $result && drop_index($table, $index);
+
+/// Define key groupingid (foreign) to be added to groups_groupings_groups
+    $table = new XMLDBTable('groups_groupings_groups');
+    $key = new XMLDBKey('groupingid');
+    $key->setAttributes(XMLDB_KEY_FOREIGN, array('groupingid'), 'groups_groupings', array('id'));
+
+/// Launch add key groupingid
+    $result = $result && drop_key($table, $key);
+
+/// Define key groupid (foreign) to be added to groups_groupings_groups
+    $key = new XMLDBKey('groupid');
+    $key->setAttributes(XMLDB_KEY_FOREIGN, array('groupid'), 'groups', array('id'));
+
+/// Launch add key groupid
+    $result = $result && drop_key($table, $key);
+
+/// Define index groupingid-groupid (unique) to be added to groups_groupings_groups
+    $index = new XMLDBIndex('groupingid-groupid');
+    $index->setAttributes(XMLDB_INDEX_UNIQUE, array('groupingid', 'groupid'));
+
+/// Launch add index groupingid-groupid
+    $result = $result && drop_index($table, $index);
+
+    return $result;
+}
+
+/** This might be useful in ddllib.php.
+ * Example:
+ * $field_seed = new XMLDBField($field_name);
+ * $field_seed->setAttributes(XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0', $previous);
+ * $result = $result && upgrade_drop_fields($table, $field_seed, $fields);
+ *
+ * @param $table XMLDBTable object.
+ * @param $field_seed XMLDBField object with attributes including 'previous' set for first field.
+ * @param $fields array of names of fields to be deleted, including the seed name.
+ */
+function upgrade_drop_fields($table, $field_seed, $fields) {
+    $result = true;
+    $field = $field_seed;
+    foreach ($fields as $field_name) {
+        $field->setName($field_name);
+        $result = $result && drop_field($table, $field);
+        $field->setPrevious($field->getName());
+    }
+    return $result;
+}
+
 ?>
diff --git a/version.php b/version.php
index cdbae7e..4516b41 100644
--- a/version.php
+++ b/version.php
@@ -6,7 +6,7 @@
 // This is compared against the values stored in the database to determine
 // whether upgrades should be performed (see lib/db/*.php)
 
-    $version = 2007081001;  // YYYYMMDD = date
+    $version = 2007081300;  // YYYYMMDD = date
                             //       XY = increments within a single day
 
     $release = '1.9 dev';   // Human-friendly version name
