diff --git a/calendar/export_execute.php b/calendar/export_execute.php
index 01c1e2f..2afb1ff 100644
--- a/calendar/export_execute.php
+++ b/calendar/export_execute.php
@@ -114,6 +114,12 @@ if ($events === false) {
 $ical = new iCalendar;
 $ical->add_property('method', 'PUBLISH');
 foreach($events as $event) {
+   if (!empty($event->modulename)) {
+        $cm = get_coursemodule_from_instance($event->modulename, $event->instance);
+        if (!groups_course_module_visible($cm)) {
+            continue;
+        }
+    }
     $ev = new iCalendar_event;
     $ev->add_property('summary', $event->name);
     $ev->add_property('description', $event->description);
diff --git a/calendar/lib.php b/calendar/lib.php
index ba43c76..796cf92 100644
--- a/calendar/lib.php
+++ b/calendar/lib.php
@@ -152,13 +152,19 @@ function calendar_get_mini($courses, $groups, $users, $cal_month = false, $cal_y
 
     // Set event course class for course events
     if (!empty($events)) {
-        foreach ($events as $event) {
+        foreach ($events as $eventid => $event) {
             if($event->courseid != 0 && $event->courseid != SITEID && $event->groupid == 0) {
                 $event->class = 'event_course'.array_search($event->courseid, $courses) % CALENDAR_MAXCOURSES;
             }
+            if (!empty($event->modulename)) {
+                $cm = get_coursemodule_from_instance($event->modulename, $event->instance);
+                if (!groups_course_module_visible($cm)) {
+                    unset($events[$eventid]);
+                }
+            }
         }
     }
-
+    
     // This is either a genius idea or an idiot idea: in order to not complicate things, we use this rule: if, after
     // possibly removing SITEID from $courses, there is only one course left, then clicking on a day in the month
     // will also set the $SESSION->cal_courses_shown variable to that one course. Otherwise, we 'd need to add extra
@@ -418,6 +424,12 @@ function calendar_get_upcoming($courses, $groups, $users, $daysinfuture, $maxeve
     if($events !== false) {
 
         foreach($events as $event) {
+            if(!empty($event->modulename)) {
+                $mod = get_coursemodule_from_instance($event->modulename, $event->instance);
+                if (!groups_course_module_visible($mod)) {
+                    continue;
+                }
+            }
 
             if($processed >= $display->maxevents) {
                 break;
diff --git a/calendar/view.php b/calendar/view.php
index ce8fcfb..d45f055 100644
--- a/calendar/view.php
+++ b/calendar/view.php
@@ -372,7 +372,17 @@ function calendar_show_month_detailed($m, $y, $courses, $groups, $users, $course
     else {
         $events = get_records_select('event', $whereclause, 'timestart');
     }
-
+    if (!empty($events)) {
+        foreach($events as $eventid => $event) {
+            if (!empty($event->modulename)) {
+                $cm = get_coursemodule_from_instance($event->modulename, $event->instance);
+                if (!groups_course_module_visible($cm)) {
+                    unset($events[$eventid]);
+                }
+            }
+        }
+    }
+    
     // Extract information: events vs. time
     calendar_events_by_day($events, $m, $y, $eventsbyday, $durationbyday, $typesbyday, $courses);
 
diff --git a/course/lib.php b/course/lib.php
index c8e5989..ec910a4 100644
--- a/course/lib.php
+++ b/course/lib.php
@@ -87,6 +87,10 @@ function print_recent_selector_form($course, $advancedfilter=0, $selecteduser=0,
                 if (!$mod->visible and !has_capability('moodle/course:viewhiddenactivities',get_context_instance(CONTEXT_MODULE, $mod->cm))) {
                     continue;
                 }
+                $mod->id = $mod->cm;
+                if (!groups_course_module_visible($mod)) {
+                    continue;
+                }
 
                 if ($mod->section > 0 and $section <> $mod->section) {
                     $activities["section/$mod->section"] = "-------------- $strsection $mod->section --------------";
@@ -1156,6 +1160,8 @@ function get_array_of_activities($courseid) {
 //  section - the number of the section (eg week or topic)
 //  name - the name of the instance
 //  visible - is the instance visible or not
+//  groupingid - grouping id
+//  groupmembersonly - is this instance visible to group members only
 //  extra - contains extra string to include in any link
 
     global $CFG;
@@ -1179,6 +1185,8 @@ function get_array_of_activities($courseid) {
                    $mod[$seq]->section = $section->section;
                    $mod[$seq]->name = urlencode(get_field($rawmods[$seq]->modname, "name", "id", $rawmods[$seq]->instance));
                    $mod[$seq]->visible = $rawmods[$seq]->visible;
+                   $mod[$seq]->groupingid = $rawmods[$seq]->groupingid;
+                   $mod[$seq]->groupmembersonly = $rawmods[$seq]->groupmembersonly;
                    $mod[$seq]->extra = "";
 
                    $modname = $mod[$seq]->mod;
@@ -1231,6 +1239,10 @@ function get_all_mods($courseid, &$mods, &$modnames, &$modnamesplural, &$modname
             if (empty($modnames[$mod->modname])) {
                 continue;
             }
+            // Check groupings
+            if (!groups_course_module_visible($mod)) {
+                continue;
+            }
             $mods[$mod->id] = $mod;
             $mods[$mod->id]->modfullname = $modnames[$mod->modname];
             if ($mod->visible or has_capability('moodle/course:viewhiddenactivities', get_context_instance(CONTEXT_COURSE, $courseid))) {
@@ -1342,7 +1354,8 @@ function print_section($course, $section, $mods, $modnamesused, $absolute=false,
             $mod = $mods[$modnumber];
 
             if (($mod->visible or has_capability('moodle/course:viewhiddenactivities', get_context_instance(CONTEXT_COURSE, $course->id))) &&
-                (!$ismoving || $mod->id != $USER->activitycopy)) {
+                (!$ismoving || $mod->id != $USER->activitycopy) &&
+                groups_course_module_visible($mod)) {
                 echo '<li class="activity '.$mod->modname.'" id="module-'.$modnumber.'">';  // Unique ID
                 if ($ismoving) {
                     echo '<a title="'.$strmovefull.'"'.
diff --git a/lib/datalib.php b/lib/datalib.php
index 48f405c..ffc76f7 100644
--- a/lib/datalib.php
+++ b/lib/datalib.php
@@ -1359,7 +1359,7 @@ function instance_is_visible($moduletype, $module) {
     global $CFG;
 
     if (!empty($module->id)) {
-        if ($records = get_records_sql("SELECT cm.instance, cm.visible
+        if ($records = get_records_sql("SELECT cm.instance, cm.visible, cm.groupingid, cm.id, cm.groupmembersonly
                                         FROM {$CFG->prefix}course_modules cm,
                                              {$CFG->prefix}modules m
                                        WHERE cm.course = '$module->course' AND
@@ -1368,7 +1368,7 @@ function instance_is_visible($moduletype, $module) {
                                              cm.instance = '$module->id'")) {
 
             foreach ($records as $record) { // there should only be one - use the first one
-                return $record->visible;
+                return $record->visible && groups_course_module_visible($record);
             }
         }
     }
diff --git a/lib/grouplib.php b/lib/grouplib.php
index daf6d1f..9294f50 100644
--- a/lib/grouplib.php
+++ b/lib/grouplib.php
@@ -154,5 +154,31 @@ function groups_get_members($groupid, $sort='lastname ASC') {
 }
 
 
-
+/**
+ * Determine if a course module is currently visible to a user
+ * @uses $USER If $userid is null, use the global object.
+ * @param int $cm The course module
+ * @param int $userid The user to check against the group.
+ * @return boolean True if the user can view the course module, false otherwise.
+ */
+function groups_course_module_visible($cm, $userid=null) {
+    global $CFG, $USER;
+    
+    if (empty($userid)) {
+        $userid = $USER->id;
+    }
+    if (empty($CFG->enablegroupings)) {
+        return(true);
+    }
+    if (empty($cm->groupmembersonly)) {
+        return(true);
+    }
+    if (has_capability('moodle/site:accessallgroups', get_context_instance(CONTEXT_MODULE, $cm->id), $userid)) {
+        return(true);
+    }
+    if (groups_has_membership($cm, $userid)) {
+        return(true);
+    }
+    return(false);
+}
 ?>
