diff --git a/course/externallib.php b/course/externallib.php
index 2d61c28..1ac91ae 100644
--- a/course/externallib.php
+++ b/course/externallib.php
@@ -1105,6 +1105,272 @@ class core_course_external extends external_api {
     }
 
     /**
+     * Returns description of method parameters
+     *
+     * @return external_function_parameters
+     * @since Moodle 2.8
+     */
+    public static function duplicate_course_multiple_parameters() {
+        return new external_function_parameters(
+            array(
+                'courseid' => new external_value(PARAM_INT, 'course to duplicate id'),
+                'destinations' => new external_multiple_structure(
+                    new external_single_structure(
+                        array(
+                            'fullname' => new external_value(PARAM_TEXT, 'duplicated course full name'),
+                            'shortname' => new external_value(PARAM_TEXT, 'duplicated course short name'),
+                            'categoryid' => new external_value(PARAM_INT, 'duplicated course category parent'),
+                            'visible' => new external_value(PARAM_INT, 'duplicated course visible, default to yes', VALUE_DEFAULT, 1),
+                            )
+                        )
+                    ),
+                'options' => new external_multiple_structure(
+                    new external_single_structure(
+                        array(
+                                'name' => new external_value(PARAM_ALPHAEXT, 'The backup option name:
+                                            "activities" (int) Include course activites (default to 1 that is equal to yes),
+                                            "blocks" (int) Include course blocks (default to 1 that is equal to yes),
+                                            "filters" (int) Include course filters  (default to 1 that is equal to yes),
+                                            "users" (int) Include users (default to 0 that is equal to no),
+                                            "role_assignments" (int) Include role assignments  (default to 0 that is equal to no),
+                                            "comments" (int) Include user comments  (default to 0 that is equal to no),
+                                            "userscompletion" (int) Include user course completion information  (default to 0 that is equal to no),
+                                            "logs" (int) Include course logs  (default to 0 that is equal to no),
+                                            "grade_histories" (int) Include histories  (default to 0 that is equal to no)'
+                                            ),
+                                'value' => new external_value(PARAM_RAW, 'the value for the option 1 (yes) or 0 (no)'
+                            )
+                        )
+                    ), VALUE_DEFAULT, array()
+                )
+            )
+        );
+    }
+
+    /**
+     * Duplicate a course 1 or more times
+     *
+     * @param int $courseid
+     * @param array $desinations Details of destination courses
+     * @param array $options List of backup options
+     * @return array New course info
+     * @since Moodle 2.8
+     */
+    public static function duplicate_course_multiple($courseid, $destinations = array(), $options = array()) {
+        global $CFG, $USER, $DB;
+        require_once($CFG->dirroot . '/backup/util/includes/backup_includes.php');
+        require_once($CFG->dirroot . '/backup/util/includes/restore_includes.php');
+
+        // Parameter validation.
+        $params = self::validate_parameters(
+                self::duplicate_course_multiple_parameters(),
+                array(
+                      'courseid' => $courseid,
+                      'destinations' => $destinations,
+                      'options' => $options
+                )
+        );
+
+        // Context validation.
+
+        if (! ($course = $DB->get_record('course', array('id'=>$params['courseid'])))) {
+            throw new moodle_exception('invalidcourseid', 'error');
+        }
+
+        // Category where duplicated course is going to be created.
+        $already_checked = array();
+        foreach ($params['destinations'] as $destination) {
+            $this_categoryid = $destination['categoryid'];
+            if (isset($already_checked[$this_categoryid]))
+                continue;
+
+            $categorycontext = context_coursecat::instance($destination['categoryid']);
+            self::validate_context($categorycontext);
+            $already_checked[$this_categoryid] = TRUE;
+        }
+
+        // Course to be duplicated.
+        $coursecontext = context_course::instance($course->id);
+        self::validate_context($coursecontext);
+
+        $backupdefaults = array(
+            'activities' => 1,
+            'blocks' => 1,
+            'filters' => 1,
+            'users' => 0,
+            'role_assignments' => 0,
+            'comments' => 0,
+            'userscompletion' => 0,
+            'logs' => 0,
+            'grade_histories' => 0
+        );
+
+        $backupsettings = array();
+        // Check for backup and restore options.
+        if (!empty($params['options'])) {
+            foreach ($params['options'] as $option) {
+
+                // Strict check for a correct value (allways 1 or 0, true or false).
+                $value = clean_param($option['value'], PARAM_INT);
+
+                if ($value !== 0 and $value !== 1) {
+                    throw new moodle_exception('invalidextparam', 'webservice', '', $option['name']);
+                }
+
+                if (!isset($backupdefaults[$option['name']])) {
+                    throw new moodle_exception('invalidextparam', 'webservice', '', $option['name']);
+                }
+
+                $backupsettings[$option['name']] = $value;
+            }
+        }
+
+        // Capability checking.
+
+        // The backup controller check for this currently, this may be redundant.
+        $already_checked = array();
+        foreach ($params['destinations'] as $destination) {
+            $this_categoryid = $destination['categoryid'];
+            if (isset($already_checked[$this_categoryid]))
+                continue;
+
+            require_capability('moodle/course:create', $categorycontext);
+            require_capability('moodle/restore:restorecourse', $categorycontext);
+
+            if (!empty($backupsettings['users']))
+                require_capability('moodle/restore:userinfo', $categorycontext);
+
+            // Check if the shortname is used.
+            if ($foundcourses = $DB->get_records('course', array('shortname'=>$destination['shortname']))) {
+                foreach ($foundcourses as $foundcourse) {
+                    $foundcoursenames[] = $foundcourse->fullname;
+                }
+
+                $foundcoursenamestring = implode(',', $foundcoursenames);
+                throw new moodle_exception('shortnametaken', '', '', $foundcoursenamestring);
+            }
+        }
+
+        require_capability('moodle/backup:backupcourse', $coursecontext);
+
+        if (!empty($backupsettings['users'])) {
+            require_capability('moodle/backup:userinfo', $coursecontext);
+        }
+
+        // Backup the course.
+
+        $bc = new backup_controller(backup::TYPE_1COURSE, $course->id, backup::FORMAT_MOODLE,
+        backup::INTERACTIVE_NO, backup::MODE_SAMESITE, $USER->id);
+
+        foreach ($backupsettings as $name => $value) {
+            $bc->get_plan()->get_setting($name)->set_value($value);
+        }
+
+        $backupid       = $bc->get_backupid();
+        $backupbasepath = $bc->get_plan()->get_basepath();
+
+        $bc->execute_plan();
+        $results = $bc->get_results();
+        $file = $results['backup_destination'];
+
+        $bc->destroy();
+
+        // Restore the backup immediately.
+
+        // Check if we need to unzip the file because the backup temp dir does not contains backup files.
+        if (!file_exists($backupbasepath . "/moodle_backup.xml")) {
+            $file->extract_to_pathname(get_file_packer(), $backupbasepath);
+        }
+
+        $normally_kept = isset($CFG->keeptempdirectoriesonbackup);
+
+        $results = array();
+
+        foreach ($params['destinations'] as $index => $destination) {
+            if (($index + 1) < sizeof($params['destinations'])) {
+                $CFG->keeptempdirectoriesonbackup = TRUE;
+            } elseif (!$normally_kept) {
+                unset($CFG->keeptempdirectoriesonbackup);
+            }
+
+            // Create new course.
+            $newcourseid = restore_dbops::create_new_course($destination['fullname'], $destination['shortname'], $destination['categoryid']);
+
+            $rc = new restore_controller($backupid, $newcourseid,
+                    backup::INTERACTIVE_NO, backup::MODE_SAMESITE, $USER->id, backup::TARGET_NEW_COURSE);
+
+            foreach ($backupsettings as $name => $value) {
+                $setting = $rc->get_plan()->get_setting($name);
+                if ($setting->get_status() == backup_setting::NOT_LOCKED) {
+                    $setting->set_value($value);
+                }
+            }
+
+            if (!$rc->execute_precheck()) {
+                $precheckresults = $rc->get_precheck_results();
+                if (is_array($precheckresults) && !empty($precheckresults['errors'])) {
+                    if (empty($CFG->keeptempdirectoriesonbackup)) {
+                        fulldelete($backupbasepath);
+                    }
+
+                    $errorinfo = '';
+
+                    foreach ($precheckresults['errors'] as $error) {
+                        $errorinfo .= $error;
+                    }
+
+                    if (array_key_exists('warnings', $precheckresults)) {
+                        foreach ($precheckresults['warnings'] as $warning) {
+                            $errorinfo .= $warning;
+                        }
+                    }
+
+                    throw new moodle_exception('backupprecheckerrors', 'webservice', '', $errorinfo);
+                }
+            }
+
+            $rc->execute_plan();
+            $rc->destroy();
+
+            $course = $DB->get_record('course', array('id' => $newcourseid), '*', MUST_EXIST);
+            $course->fullname = $destination['fullname'];
+            $course->shortname = $destination['shortname'];
+            $course->visible = $destination['visible'];
+
+            // Set shortname and fullname back.
+            $DB->update_record('course', $course);
+
+            $results[] = array('id' => $course->id, 'shortname' => $course->shortname);
+        }
+
+        if (empty($CFG->keeptempdirectoriesonbackup)) {
+            fulldelete($backupbasepath);
+        }
+
+        // Delete the course backup file created by this WebService. Originally located in the course backups area.
+        $file->delete();
+
+        return $results;
+    }
+
+    /**
+     * Returns description of method result value
+     *
+     * @return external_description
+     * @since Moodle 2.6
+     */
+    public static function duplicate_course_multiple_returns() {
+        return new external_single_structure(
+            array(
+                array(
+                    'id'       => new external_value(PARAM_INT, 'course id'),
+                    'shortname' => new external_value(PARAM_TEXT, 'short name'),
+                )
+            )
+        );
+    }
+
+    /**
      * Returns description of method parameters for import_course
      *
      * @return external_function_parameters
diff --git a/local/tass/db_import.php b/local/tass/db_import.php
index 891e904..b6c79b2 100644
--- a/local/tass/db_import.php
+++ b/local/tass/db_import.php
@@ -513,6 +513,8 @@ class tass_db_import_cohort extends tass_db_import {
         $result = core_cohort_external::create_cohorts($param);
         $this->debug(10, "Calling create_cohorts returned: " . print_r($result, true));
 
+        $result = array_column($result, NULL, "name");
+
         // Create matching courses and add the cohorts.
         if (!isset($this->no_course)) {
             //echo "Seeking to create courses for cohorts...\n";
@@ -537,21 +539,34 @@ class tass_db_import_cohort extends tass_db_import {
             $cohort_plugin = enrol_get_plugin('cohort');
             $role = $DB->get_record('role', array('shortname' => (isset($this->class_config['role']) ? $this->class_config['role'] : "student")));
 
-            foreach ($result as $adding) {
-                $this->debug(10, "Creating cohort course {$adding['name']}.\n");
-                if (is_null($template_id)) {
+            if (is_null($template_id)) {
+                foreach ($result as $adding) {
+                    $this->debug(10, "Creating cohort course {$adding['name']}.\n");
                     $courses = core_course_external::create_courses(array(array('fullname' => $adding['name'], 'shortname' => $adding['name'], 'categoryid' => $category)));
-                    $course = $courses[0];
-                } else {
-                    $course = core_course_external::duplicate_course($template_id, $adding['name'], $adding['name'], $category);
-                }
-                $course_object = new stdClass();
-                $course_object->id = $course['id'];
+                    $course_object = new stdClass();
+                    $course_object->id = $courses[0]['id'];
 
-                // Enrol the cohort.
-                $this->debug(1, "Enrolling the cohort...");
-                $id = $cohort_plugin->add_instance($course_object, array('customint1'=>$adding['id'], 'roleid'=>$role->id));
-                $this->debug(1, " done.\n");
+                    // Enrol the cohort.
+                    $this->debug(1, "Enrolling the cohort...");
+                    $id = $cohort_plugin->add_instance($course_object, array('customint1'=>$result[$courses[0]['shortname']]['id'], 'roleid'=>$role->id));
+                    $this->debug(1, " done.\n");
+                }
+            } else {
+                $dup_arg = array();
+                foreach ($result as $adding) {
+                    $this->debug(10, "Creating cohort course {$adding['name']}.\n");
+                    $dup_arg[] = array('fullname' => $adding['name'], 'shortname' => $adding['name'], 'categoryid' => $category);
+                }
+                $courses = core_course_external::duplicate_course_multiple($template_id, $dup_arg);
+                foreach ($courses as $course) {
+                    $course_object = new stdClass();
+                    $course_object->id = $course['id'];
+
+                    // Enrol the cohort.
+                    $this->debug(1, "Enrolling the cohort...");
+                    $id = $cohort_plugin->add_instance($course_object, array('customint1'=>$result[$course['shortname']]['id'], 'roleid'=>$role->id));
+                    $this->debug(1, " done.\n");
+                }
             }
         }
 
@@ -795,13 +810,20 @@ class tass_db_import_course extends tass_db_import {
         $num_to_add = sizeof($instances);
         $index = 0;
 
-        foreach($instances as $instance) {
-            $index++;
-            $this->debug(1, "Adding course {$instance->fullname} ({$index}/${num_to_add}).\n");
-            if (is_null($this->template_id)) {
+        if (is_null($this->template_id)) {
+            foreach($instances as $instance) {
+                $index++;
+                $this->debug(1, "Adding course {$instance->fullname} ({$index}/${num_to_add}).\n");
                 core_course_external::create_courses(array(array('fullname' => $instance->fullname, 'shortname' => $instance->shortname, 'categoryid' => $category, 'idnumber' => $instance->idnumber)));
-            } else {
-                $result = core_course_external::duplicate_course($this->template_id, $instance->fullname, $instance->shortname, $category);
+            }
+        } else {
+            $args = array();
+            $this->debug(1, "Adding ${num_to_add} courses.\n");
+            foreach($instances as $instance) {
+                $args[] = array('fullname' => $instance->fullname, 'shortname' => $instance->shortname, 'categoryid' => $category);
+            }
+            $result = core_course_external::duplicate_course_multiple($this->template_id, $args);
+            foreach($instances as $instance) {
                 core_course_external::update_courses(array(array(
                                 'id' => $result['id'],
                                 'idnumber' => $instance->idnumber,
