diff -Nuar standard_moodle/course/lib.php my_moodle/course/lib.php
--- standard_moodle/course/lib.php	2011-03-14 09:13:20.000000000 +0300
+++ my_moodle/course/lib.php	2011-03-10 15:01:57.000000000 +0300
@@ -3060,6 +3060,7 @@
 
     if (!isset($str)) {
         $str->assign         = get_string("assignroles", 'role');
+        $str->copy           = get_string("copy");
         $str->delete         = get_string("delete");
         $str->move           = get_string("move");
         $str->moveup         = get_string("moveup");
@@ -3192,6 +3193,11 @@
            '&amp;sesskey='.$sesskey.$section.'"><img'.
            ' src="'.$OUTPUT->pix_url('t/edit') . '" class="iconsmall" '.
            ' alt="'.$str->update.'" /></a>'."\n".
+           '<a class="editing_copy" title="'.$str->copy.'" href="'.$path.'/mod.php?add='.$mod->modname.
+           '&amp;type=&amp;id='.$mod->course.'&amp;section='.$mod->sectionnum.
+           '&amp;copyfrom='.$mod->id.'&amp;sesskey='.$sesskey.$section.'"><img'.
+           ' src="'.$OUTPUT->pix_url('t/copy') . '" class="iconsmall" '.
+           ' alt="'.$str->copy.'" /></a>'."\n".
            '<a class="editing_delete" title="'.$str->delete.'" href="'.$path.'/mod.php?delete='.$mod->id.
            '&amp;sesskey='.$sesskey.$section.'"><img'.
            ' src="'.$OUTPUT->pix_url('t/delete') . '" class="iconsmall" '.
diff -Nuar standard_moodle/course/modedit.php my_moodle/course/modedit.php
--- standard_moodle/course/modedit.php	2011-03-14 09:13:20.000000000 +0300
+++ my_moodle/course/modedit.php	2011-03-14 09:31:22.000000000 +0300
@@ -35,6 +35,7 @@
 $update = optional_param('update', 0, PARAM_INT);
 $return = optional_param('return', 0, PARAM_BOOL);    //return to course/view.php if false or mod/modname/view.php if true
 $type   = optional_param('type', '', PARAM_ALPHANUM); //TODO: hopefully will be removed in 2.0
+$copyfrom = optional_param('copyfrom', 0, PARAM_INT);
 
 $url = new moodle_url('/course/modedit.php');
 if (!empty($return)) {
@@ -63,41 +64,92 @@
         print_error('moduledisable');
     }
 
-    $cm = null;
-
-    $data = new stdClass();
+    if (!empty($copyfrom)) {
+        $cm = get_coursemodule_from_id('', $copyfrom, 0, false, MUST_EXIST);
+        $data = $DB->get_record($module->name, array('id'=>$cm->instance), '*', MUST_EXIST);
+        $data->visible            = $cm->visible; //??  $cw->visible ? $cm->visible : 0; // section hiding overrides
+        $data->cmidnumber         = $cm->idnumber;          // The cm IDnumber
+        $data->groupmode          = groups_get_activity_groupmode($cm); // locked later if forced
+        $data->groupingid         = $cm->groupingid;
+        $data->groupmembersonly   = $cm->groupmembersonly;
+        $data->instance           = $cm->instance;
+        $data->completion         = $cm->completion;
+        $data->completionview     = $cm->completionview;
+        $data->completionexpected = $cm->completionexpected;
+        $data->completionusegrade = is_null($cm->completiongradeitemnumber) ? 0 : 1;
+        if (plugin_supports('mod', $data->modulename, FEATURE_MOD_INTRO, true)) {
+            $draftideditor = file_get_submitted_draft_itemid('introeditor');
+            $currentintro = file_prepare_draft_area($draftideditor, $context->id, 'mod_'.$data->modulename, 'intro', 0, array('subdirs'=>true), $data->intro);
+            $data->introeditor = array('text'=>$currentintro, 'format'=>$data->introformat, 'itemid'=>$draftideditor);
+        }
+    } else {
+        $cm = null;
+        $data = new stdClass();
+        $data->visible          = $cw->visible;
+        $data->instance         = '';
+        $data->groupmode        = $course->groupmode;
+        $data->groupingid       = $course->defaultgroupingid;
+        $data->groupmembersonly = 0;
+        if (plugin_supports('mod', $data->modulename, FEATURE_MOD_INTRO, true)) {
+            $draftideditor = file_get_submitted_draft_itemid('introeditor');
+            file_prepare_draft_area($draftideditor, null, null, null, null);
+            $data->introeditor = array('text'=>'', 'format'=>FORMAT_HTML, 'itemid'=>$draftideditor); // TODO: add better default
+        }
+    }
     $data->section          = $section;  // The section number itself - relative!!! (section column in course_sections)
-    $data->visible          = $cw->visible;
     $data->course           = $course->id;
     $data->module           = $module->id;
     $data->modulename       = $module->name;
-    $data->groupmode        = $course->groupmode;
-    $data->groupingid       = $course->defaultgroupingid;
-    $data->groupmembersonly = 0;
     $data->id               = '';
-    $data->instance         = '';
     $data->coursemodule     = '';
     $data->add              = $add;
     $data->return           = 0; //must be false if this is an add, go back to course view on cancel
 
-    if (plugin_supports('mod', $data->modulename, FEATURE_MOD_INTRO, true)) {
-        $draftid_editor = file_get_submitted_draft_itemid('introeditor');
-        file_prepare_draft_area($draftid_editor, null, null, null, null);
-        $data->introeditor = array('text'=>'', 'format'=>FORMAT_HTML, 'itemid'=>$draftid_editor); // TODO: add better default
-    }
-
     if (!empty($type)) { //TODO: hopefully will be removed in 2.0
         $data->type = $type;
     }
-
+    if (!empty($copyfrom)) {
+        if ($items = grade_item::fetch_all(array('itemtype'=>'mod', 'itemmodule'=>$data->modulename,
+                                                 'iteminstance'=>$data->instance, 'courseid'=>$course->id))) {
+            // add existing outcomes
+            foreach ($items as $item) {
+                if (!empty($item->outcomeid)) {
+                    $data->{'outcome_'.$item->outcomeid} = 1;
+                }
+            }
+
+            // set category if present
+            $gradecat = false;
+            foreach ($items as $item) {
+                if ($gradecat === false) {
+                    $gradecat = $item->categoryid;
+                    continue;
+                }
+                if ($gradecat != $item->categoryid) {
+                    //mixed categories
+                    $gradecat = false;
+                    break;
+                }
+            }
+            if ($gradecat !== false) {
+                // do not set if mixed categories present
+                $data->gradecat = $gradecat;
+            }
+        }
+    }
     $sectionname = get_section_name($course, $cw);
     $fullmodulename = get_string('modulename', $module->name);
 
-    if ($data->section && $course->format != 'site') {
+    if ($data->section && $course->format != 'site' && empty($copyfrom)) {
         $heading = new stdClass();
         $heading->what = $fullmodulename;
         $heading->to   = $sectionname;
         $pageheading = get_string('addinganewto', 'moodle', $heading);
+    } else if ($data->section && $course->format != 'site' && !empty($copyfrom)) {
+        $heading = new stdClass();
+        $heading->what = $fullmodulename;
+        $heading->in = $sectionname;
+        $pageheading = get_string('copyingain', 'moodle', $heading);
     } else {
         $pageheading = get_string('addinganew', 'moodle', $fullmodulename);
     }
diff -Nuar standard_moodle/course/mod.php my_moodle/course/mod.php
--- standard_moodle/course/mod.php	2011-03-14 09:13:20.000000000 +0300
+++ my_moodle/course/mod.php	2011-03-10 15:01:57.000000000 +0300
@@ -71,8 +71,9 @@
     $section     = required_param('section', PARAM_INT);
     $type        = optional_param('type', '', PARAM_ALPHA);
     $returntomod = optional_param('return', 0, PARAM_BOOL);
+    $copyfrom    = optional_param('copyfrom', 0, PARAM_INT);
 
-    redirect("$CFG->wwwroot/course/modedit.php?add=$add&type=$type&course=$id&section=$section&return=$returntomod");
+    redirect("$CFG->wwwroot/course/modedit.php?add=$add&type=$type&course=$id&section=$section&return=$returntomod&copyfrom=$copyfrom");
 
 } else if (!empty($update)) {
     if (!$cm = get_coursemodule_from_id('', $update, 0, true)) {
diff -Nuar standard_moodle/lang/en/moodle.php my_moodle/lang/en/moodle.php
--- standard_moodle/lang/en/moodle.php	2011-03-14 09:13:20.000000000 +0300
+++ my_moodle/lang/en/moodle.php	2011-03-10 15:01:57.000000000 +0300
@@ -264,6 +264,7 @@
 $string['cookiesnotenabled'] = 'Unfortunately, cookies are currently not enabled in your browser';
 $string['copy'] = 'copy';
 $string['copyasnoun'] = 'copy';
+$string['copyingain'] = 'Copying a {$a->what} in {$a->in}';
 $string['copyingcoursefiles'] = 'Copying course files';
 $string['copyingsitefiles'] = 'Copying site files used in course';
 $string['copyinguserfiles'] = 'Copying user files';
diff -Nuar standard_moodle/lib/ajax/section_classes.js my_moodle/lib/ajax/section_classes.js
--- standard_moodle/lib/ajax/section_classes.js	2011-03-14 09:13:20.000000000 +0300
+++ my_moodle/lib/ajax/section_classes.js	2011-03-10 15:01:57.000000000 +0300
@@ -631,6 +631,7 @@
     var moveLeft = false;
     var moveRight = false;
     var updateButton = null;
+    var copyButton = null;
     var assignButton = null;
 
     // for RTL support
@@ -641,6 +642,8 @@
             moveLeft = true;
         } else if (buttons[x].className == 'editing_moveright') {
             moveRight = true;
+        } else if (buttons[x].className == 'editing_copy') {
+            copyButton = buttons[x].cloneNode(true);
         } else if (buttons[x].className == 'editing_update') {
             updateButton = buttons[x].cloneNode(true);
         } else if (buttons[x].className == 'editing_assign') {
@@ -690,6 +693,7 @@
 
     // Add edit button back in.
     commandContainer.appendChild(updateButton);
+    commandContainer.appendChild(copyButton);
 
     // Add the delete button.
     var button = main.mk_button('a', main.portal.icons['delete'], main.portal.strings['delete'], null, [['class', 'iconsmall']]);
